home *** CD-ROM | disk | FTP | other *** search
/ CD BIT 75 / CD BIT 75.iso / Software / SinfoSeguros / MSDE / Setup / SqlRun.cab / sp3Tools80.sql.185C1D8F_1545_4277_BB64_857D2622DB57 < prev    next >
Encoding:
Text File  |  2002-10-20  |  137.7 KB  |  3,498 lines

  1. /*------------------------------------------------------------------------------
  2.  
  3. 80SP3-TOOLS.SQL
  4.  
  5. THIS SCRIPT TAKES THE TOOLS STORED PROCS FROM 8.0, SP1, AND SP2 TO SP3.
  6.  
  7. Changes in this file reflects changes in the following files:
  8.     INSTMSDB.SQL
  9.     SQLDMO.SQL
  10.     XPSTAR.SQL
  11.     SQLTRACE.SQL
  12.     WEB.SQL
  13.  
  14. Notes:
  15. 80SP1-TOOLS.SQL AND 80SP2-TOOLS.SQL WILL *NOT* RUN WHEN APPLYING SP3
  16. ------------------------------------------------------------------------------*/
  17.  
  18. PRINT N''
  19. PRINT N'Updating database objects, executing 80SP3-TOOLS.SQL'
  20. PRINT N'Started at ' + convert(nvarchar(25), getdate())
  21. PRINT N''
  22. go
  23.  
  24. --------------------------------------------------------------------------------
  25. -- VERIFY Server is started in single-user-mode (catalog-updates enabled), 
  26. -- and start marking of system-objects.
  27. --------------------------------------------------------------------------------
  28. use master
  29. go
  30.  
  31. exec dbo.sp_configure 'allow updates',1
  32. go
  33.  
  34. reconfigure with override
  35. go
  36.  
  37. exec sp_MS_upd_sysobj_category 1
  38. go
  39.  
  40.  
  41.  
  42. --------------------------------------------------------------------------------
  43. -- BEGIN OF CHANGE SECTION:
  44. -- Add change sprocs between here and the END OF CHANGE SECTION comment.
  45. --------------------------------------------------------------------------------
  46.  
  47. --------------------------------------------------------------------------------
  48. -- SQLDMO stored procedures added after release into sqldmo.sql file
  49. --
  50. -- sp_MSobjectprivs
  51. --------------------------------------------------------------------------------
  52.  
  53. /**************************************************************/
  54. /* sp_MSobjectprivs                                           */
  55. /**************************************************************/
  56. if exists (select * from master..sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSobjectprivs')
  57.     drop procedure dbo.sp_MSobjectprivs
  58. go
  59.  
  60. print N''
  61. print N'Creating procedure sp_MSobjectprivs...'
  62. go
  63.  
  64. create proc dbo.sp_MSobjectprivs
  65.     @objname nvarchar(776) = null,
  66.     @mode nvarchar(10) = N'object',    
  67.     @objid int = null,                
  68.     @srvpriv int = null,            
  69.     @prottype int = null,            
  70.     @grantee nvarchar(258) = null,        
  71.     @flags int = 0,
  72.     @rollup int = 0
  73. as
  74.     create table #objs(id  int NOT NULL)
  75.  
  76.     /* Temp table will hold output for final select */
  77.     create table #output (
  78.         action      int  NOT NULL,
  79.         colid       int  NULL,
  80.         uid         int  NOT NULL,
  81.         protecttype int  NOT NULL,
  82.         id          int  NOT NULL,
  83.         grantor     int
  84.     )
  85.  
  86.     create table #tmp(
  87.         action   int   NOT NULL,
  88.         uid      int   NOT NULL,
  89.         protecttype int  NOT NULL,
  90.     )
  91.  
  92.    /* mode    : 'object', 'user' or 'column'*/
  93.    /*
  94.     * Note:  This was expanded for 6.5 due to changes in sysprotects.columns usage, affecting
  95.     * CPermission::ListPrivilegeColumns.  The following additional parameters are for this.
  96.     */
  97.    /* objid   : ID of the object we're querying */
  98.    /* srvpriv : privilege that we're querying for (e.g. select) */
  99.    /* prottype: Protect type, e.g. GRANT/REVOKE */
  100.    /* grantee : Grantee name. */
  101.  
  102.    /*** @flags added for DaVinci uses.  If the bit isn't set, use 6.5 ***/
  103.    /*** sp_MSobjectprivs '%s'                                         ***/
  104.  
  105.    /* 8.0: mode 'column', and grantee != null, we want user column level permissions for CTable/CView::ListUserColumnPermissions */
  106.    /*      @rollup added to indicate special rollup result set for column level permission, set to 1 to roll up */
  107.  
  108.     /* @flags is for daVinci */
  109.     if (@flags is null)
  110.         select @flags = 0
  111.  
  112.     /* If @objid is not null, this is for the new query for perm cols. */
  113.     if (@objid is not null) begin
  114.         select u.name, o.name, a = col_name(p.id, a.number), a.low, a.high, a.number
  115.             from master.dbo.spt_values a, dbo.sysprotects p, dbo.sysobjects o, dbo.sysusers u
  116.             where p.id = @objid and p.action = @srvpriv and p.protecttype = @prottype
  117.             and p.uid = user_id(@grantee)
  118.             and p.columns != 0x01 and o.id = p.id and u.uid = o.uid
  119.                 and convert(tinyint, substring(isnull(p.columns, 0x01), a.low, 1)) &
  120.                     -- 6.5 changed so that the bit 0 position is an "invert the bits" indicator:
  121.                     --        when 0, behaviour is the same as in prior versions, and other bits
  122.                     --            indicate columns with the specified privilege
  123.                     --        when 1, the other bits are indicate columns lacking the specified privilege
  124.                     a.high <> (case when (substring(isnull(p.columns, 0x00), 1, 1) & 1 = 0) then 0 else a.high end)
  125.                     and col_name(p.id, a.number) is not null
  126.                     and a.type = N'P' and a.number <= (select count(*) from dbo.syscolumns where id = @objid) order by a
  127.         return 0
  128.     end
  129.  
  130.     set nocount on
  131.  
  132.     /*
  133.      * To get around a 4.21 subquery bug where returning count(*) of 0 (for proc cols)
  134.      * causes the result set to return no rows, we need two passes; one to get the
  135.      * objects, and another to explicitly use a value (@cols) instead of a subquery.
  136.      */
  137.     declare @id int, @uid int, @cols int
  138.     select @id = null, @uid = null
  139.     if (@mode like N'us%') begin
  140.        select @uid = user_id(@objname)
  141.    end else if (@mode like N'col%') and (@objname is null) and (@grantee is not null) begin
  142.       /* 8.0, special path to get column level permissions from all objects on the specified user */
  143.       select @uid = user_id(@grantee)
  144.     end else begin
  145.       select @id = object_id(@objname)
  146.    end
  147.     if (@id is null and @uid is null) begin
  148.         RAISERROR (15001, -1, -1, @objname)
  149.         return 1
  150.     end
  151.  
  152.     /* Get a temp list of objects we're interested in.  Do not include repl_* users. */
  153.    /* This is the original code */
  154.    insert #objs select distinct p.id from dbo.sysprotects p
  155.        where (@id is null or p.id = @id)
  156.           and (@uid is null or p.uid = @uid)
  157.        and p.action in (193, 195, 196, 197, 224, 26) and p.uid not in (16382, 16383)
  158.  
  159.     /* Use a "fake cursor" by deleting successive id's from #objs, as this must run on 4.21 */
  160.     select @id = min(id) from #objs
  161.     while (@id is not null) begin
  162.         select @cols = count(*) from dbo.syscolumns c where c.id = @id
  163.       /* sysprotects.columns is for SELECT and UPDATE, NULL if it is INSERT or DELETE, since INSERT and DELETE can not be applied to column level */
  164.       insert #output select p.action, (case when p.columns is null then -1 else a.number end), p.uid, p.protecttype, p.id, p.grantor
  165.          from master.dbo.spt_values a, dbo.sysprotects p
  166.          where convert(tinyint, substring( isnull(p.columns, 0x01), a.low, 1)) & a.high !=0
  167.          and (p.id = @id)
  168.          and (@uid is null or p.uid = @uid)
  169.          and a.number <= @cols
  170.          and a.type = N'P'
  171.  
  172.       declare @count int, @whataction int, @whatid int, @dup int, @whatprot int
  173.  
  174.       /* First pass to correct duplicates */
  175.       select @count = count(*) from #output where id = @id and colid in (0, -1) and protecttype in (205, 204)
  176.       if ( @count > 0 ) begin
  177.          /* We might have duplicate rows for permission on single coulmn(s) at this point */
  178.          /* Use a fake cursor to remove the duplicates first. */
  179.          insert #tmp select action, uid, protecttype from #output where id = @id and colid in (0, -1) and protecttype in (205, 204)
  180.          select @whataction = min(action) from #tmp
  181.          select @whatid = uid from #tmp where action = @whataction
  182.          while (@whataction is not null) begin
  183.             if (@mode like N'col%') and (@objname is null) and (@grantee is not null) begin
  184.                /* Special case for column level permissions on ALL objects for the specified user, we don't want the row(s) on the entire table */
  185.                /* and we don't want the possible duplicate rows in single column(s) */
  186.                delete #output where (@whatid = uid) and (colid not in (0, -1)) and (protecttype in (205, 204)) and action = @whataction
  187.                       and (exists (select * from #output where (@whatid = uid) and (colid in (0, -1)) and action = @whataction) and (id = @id))
  188.                delete #output where (@whatid = uid) and (colid in (0, -1)) and (action = @whataction) and (id = @id)
  189.             end else if (@mode like N'use%') and (@objname is not null) begin
  190.                /* Special case for the user mode, we do want to keep the entire table permissions */
  191.                delete #output where (@whatid = uid) and (colid not in (0, -1)) and (protecttype in (205, 204)) and action = @whataction and (id = @id)
  192.             end else begin
  193.                /* Other cases */
  194.                delete #output where (@whatid = uid) and (colid not in (0, -1)) and (protecttype in (205, 204)) and action = @whataction
  195.             end
  196.  
  197.             delete #tmp where @whatid = uid
  198.             select @whataction = min(action) from #tmp
  199.             select @whatid = uid from #tmp where action = @whataction
  200.          end
  201.          delete #tmp
  202.       end
  203.  
  204.       /* Second pass to correct protect type */
  205.       select @count = count(*) from #output where id = @id and colid in (0, -1)
  206.       if ( @count > 0 ) begin
  207.          /* use another fake cursor to correct the protecttype */
  208.          /* if there are multiple rows in #output for the same id and action, and if colid = 0 exist */
  209.          /* then other rows should have different protecttype from the one in colid = 0 row */
  210.          insert #tmp select action, uid, protecttype from #output where id = @id and colid in (0, -1)
  211.          select @whataction = min(action) from #tmp
  212.          select @whatid = uid from #tmp where action = @whataction
  213.          select @whatprot = protecttype from #tmp where uid = @whatid and action = @whataction
  214.          while (@whataction is not null) begin
  215.                delete #output where id = @id and colid not in (0, -1) and @whataction = action and @whatid = uid and @whatprot = protecttype
  216.                delete #tmp where action = @whataction and @whatid = uid
  217.                select @whataction = min(action) from #tmp
  218.                select @whatid = uid from #tmp where action = @whataction
  219.                select @whatprot = protecttype from #tmp where uid = @whatid and action = @whataction
  220.          end
  221.          delete #tmp
  222.       end
  223.  
  224.         /* Increment our "fake cursor" column and get the next one. */
  225.         delete #objs where id = @id
  226.         select @id = min(id) from #objs
  227.     end
  228.  
  229.     /*
  230.      * Organize so that the non-collist privileges are returned first.. this allows
  231.      * scripting to combine them.  sysprotects.action is tinyint, so the hibyte won't conflict.
  232.      */
  233.  
  234.     update #output set action = action | 0x10000000 where colid <> 0
  235.  
  236.     /*
  237.      *  BUG 58252  
  238.      *  Delete the columns that was droped
  239.      */
  240.     delete from #output where colid not in (0, -1) and col_name(id, colid) is null
  241.  
  242.  
  243.     /*
  244.      * Order output by uid so Public will script before other groups (we need to script privs for public before
  245.      * other groups, before users; otherwise sysprotects doesn't hold onto things right).  Sub-order is by object id
  246.      * so we know when we're done with one object and onto the next, then by protecttype to group all GRANTs and
  247.      * REVOKEs together, and lastly by action (including ORDER_ACTION_BIT so scripting can be more efficient)
  248.      * because we may have multiple rows for columns.
  249.      */
  250.  
  251.     set nocount off
  252.    if (@mode not like N'col%') begin
  253.       /* Mode is not 'column', do the regular stuff */
  254.        select p.action & ~convert(int, 0x10000000), N'column' = col_name(p.id, p.colid), p.uid, N'username' = user_name(p.uid),
  255.                p.protecttype, o.name, N'owner' = user_name(o.uid), p.id, N'grantor' = user_name(p.grantor)
  256.              from #output p, dbo.sysobjects o
  257.              where o.id = p.id
  258.              order by p.uid, p.id, p.protecttype, p.action
  259.    end else
  260.    /* Below are spcial cases for column level permissions */
  261.    if (@objname is null) and (@grantee is not null) and (@rollup = 0) begin
  262.       /* 8.0, special path to get column level permissions from all objects on the specified user */
  263.       select N'ObjectName' = o.name, N'Owner' = user_name(o.uid), N'ColumnName' = col_name(p.id, p.colid), o.sysstat & 0x0f, p.id,
  264.              p.action & ~convert(int, 0x10000000), p.protecttype
  265.              from #output p, dbo.sysobjects o
  266.              where p.id = o.id and p.uid = user_id(@grantee) and col_name(p.id, p.colid) is not null
  267.              order by p.uid, p.id, p.protecttype, p.action
  268.     end else if (@objname is not null) and (@grantee is not null) and (@rollup = 0) begin
  269.       /* 8.0, mode 'column', and grantee != null, we want column level permissions on this object for this user */
  270.       select N'column' = col_name(p.id, p.colid), N'owner' = user_name(o.uid), N'username' = user_name(p.uid), o.sysstat & 0x0f, p.id,
  271.              p.action & ~convert(int, 0x10000000), p.protecttype
  272.              from #output p, dbo.sysobjects o
  273.              where o.id = p.id and p.uid = user_id(@grantee) and col_name(p.id, p.colid) is not null
  274.              order by p.uid, p.id, p.protecttype, p.action
  275.    end else if (@objname is not null) and (@grantee is null) and (@rollup = 0) begin
  276.       /* 8.0, mode 'column', and grantee = null, we want column level permissions on this object for all users */
  277.       select N'column' = col_name(p.id, p.colid), N'owner' = user_name(o.uid), N'username' = user_name(p.uid), o.sysstat & 0x0f, p.id,
  278.              p.action & ~convert(int, 0x10000000), p.protecttype
  279.              from #output p, dbo.sysobjects o
  280.              where o.id = p.id and col_name(p.id, p.colid) is not null
  281.              order by p.uid, p.id, p.protecttype, p.action
  282.    end else if (@objname is null) and (@grantee is not null) and (@rollup <> 0) begin
  283.       /* 8.0, roll up version of the special path to get column level permissions from all objects on the specified user */
  284.       select distinct N'ObjectName' = o.name, N'owner' = user_name(o.uid),
  285.              N'Select' = (case when ((p.action & ~convert(int, 0x10000000))=193) then 1 else 0 end),
  286.              N'Update' = (case when ((p.action & ~convert(int, 0x10000000))=197) then 1 else 0 end),
  287.              N'Type' = p.protecttype
  288.              from #output p, dbo.sysobjects o
  289.              where p.id = o.id and p.uid = user_id(@grantee) and col_name(p.id, p.colid) is not null
  290.              order by o.name
  291.    end else if (@objname is not null) and (@grantee is null) and (@rollup <> 0) begin
  292.       /* 8.0, roll up version of the special path to return column level permissions on this object for all users */
  293.       select distinct N'UserName' = user_name(p.uid),
  294.              N'Select' = (case when ((p.action & ~convert(int, 0x10000000))=193) then 1 else 0 end),
  295.              N'Update' = (case when ((p.action & ~convert(int, 0x10000000))=197) then 1 else 0 end),
  296.              N'Type' = p.protecttype
  297.              from #output p, dbo.sysobjects o
  298.              where o.id = p.id and col_name(p.id, p.colid) is not null
  299.              order by user_name(p.uid)
  300.    end else begin
  301.       raiserror 55555 N'Invalid parameter combinations.'
  302.         return 1
  303.    end
  304. go
  305. /* End sp_MSobjectprivs */
  306.  
  307.  
  308. exec sp_MS_marksystemobject sp_MSobjectprivs
  309. go
  310.  
  311. grant execute on sp_MSobjectprivs to public
  312.  
  313. --------------------------------------------------------------------------------
  314. -- END SQLDMO SECTION
  315. --------------------------------------------------------------------------------
  316.  
  317. --------------------------------------------------------------------------------
  318. -- Changes made to XPSTAR.sql file for SP1
  319. --
  320. -- xp_adsirequest          
  321. -- sp_ActiveDirectory_Obj  
  322. -- xp_GetAdminGroupName       
  323. -- sp_ActiveDirectory_SCP  
  324. --------------------------------------------------------------------------------
  325.  
  326.  
  327. /**************************************************************/
  328. /* xp_terminate_process                                       */
  329. /**************************************************************/
  330. if exists (select * from master.dbo.sysobjects where name = N'xp_terminate_process' and type = N'X')
  331.     exec sp_dropextendedproc N'xp_terminate_process'
  332. go
  333.  
  334. /**************************************************************/
  335. /* xp_adsirequest                                             */
  336. /**************************************************************/
  337. if exists (select * from sysobjects where name = N'xp_adsirequest' and type = N'X')
  338.     exec sp_dropextendedproc N'xp_adsirequest'
  339. go
  340.  
  341. print N''
  342. print N'Creating extended stored procedure xp_adsirequest...'
  343. go
  344.  
  345. exec sp_addextendedproc N'xp_adsirequest',N'xpstar.dll'
  346. go
  347.  
  348. /**************************************************************/
  349. /* sp_ActiveDirectory_Obj                                     */
  350. /**************************************************************/
  351. if exists (select * from sysobjects where name = N'sp_ActiveDirectory_Obj' and type = N'P')
  352.     drop procedure sp_ActiveDirectory_Obj
  353. go
  354.  
  355. print N''
  356. print N'Creating procedure sp_ActiveDirectory_Obj...'
  357. go
  358.  
  359. create proc dbo.sp_ActiveDirectory_Obj
  360.     @Action          nvarchar(10) = N'create',    -- create, update, delete
  361.     @ObjType         nvarchar(15) = N'database',    -- database, publication
  362.     @ObjName         sysname  = null,        -- object name
  363.     @DatabaseName    sysname = null,         -- database name for publication object
  364.     @GUIDName        sysname = null          -- GUID for publication update and delete
  365. as
  366. begin
  367.    /* create : create the object under the current SCP object. */
  368.    /* update : update the object under the SCP object.         */
  369.    /* delete : delete the object under the SCP object.         */
  370.  
  371.    SET NOCOUNT ON
  372.  
  373.    DECLARE @isdbowner int
  374.    DECLARE @cmd nvarchar(255)
  375.    DECLARE @commonname nvarchar(300)
  376.    DECLARE @retcode int
  377.    DECLARE @nAction nvarchar(3)
  378.    DECLARE @Tmp nvarchar(10)
  379.    DECLARE @dbname sysname
  380.  
  381.    DECLARE @retval int
  382.    DECLARE @SQLADSI_COM_ERROR int
  383.    DECLARE @SQLADSI_UNEXP_ERROR int
  384.    DECLARE @SQLADSI_SCP_NOT_FOUND int
  385.    DECLARE @SQLADSI_SVC_ACCT_ERROR int
  386.    DECLARE @SQLADSI_CANNOT_START_HLP int
  387.    DECLARE @SQLADSI_TIMEOUT_WAIT_HLP int
  388.    DECLARE @SQLADSI_AD_NOT_INSTALLED int
  389.    DECLARE @SQLADSI_PROXY_ACCT_ERROR int
  390.  
  391.    SELECT @SQLADSI_COM_ERROR = 536870913
  392.    SELECT @SQLADSI_UNEXP_ERROR = 536870914
  393.    SELECT @SQLADSI_SCP_NOT_FOUND = 536870915
  394.    SELECT @SQLADSI_SVC_ACCT_ERROR = 536870916
  395.    SELECT @SQLADSI_CANNOT_START_HLP = 536870917
  396.    SELECT @SQLADSI_TIMEOUT_WAIT_HLP = 536870918
  397.    SELECT @SQLADSI_AD_NOT_INSTALLED = 536870919
  398.    SELECT @SQLADSI_PROXY_ACCT_ERROR = 536870920
  399.  
  400.    /* check permissions
  401.    IF (not is_srvrolemember(N'sysadmin') = 1)
  402.    begin
  403.       raiserror(15003,-1,-1, N'sysadmin')
  404.       return 1
  405.    end
  406.    */
  407.  
  408.    /* If publication object, we need both object name and database name */
  409.    if ((UPPER(@ObjType) in (N'PUBLICATION')) and ((@ObjName is null) or (@DatabaseName is null)))
  410.    begin
  411.       raiserror(14200, -1, -1, N'@ObjName or @DatabaseName')
  412.       return 1
  413.    end
  414.  
  415.  
  416.    /* check parameters */
  417.    if (@Action is null OR UPPER(@Action) not in (N'CREATE', N'UPDATE', N'DELETE'))
  418.    begin
  419.       raiserror(14266, -1, -1, N'@Action', N'CREATE, UPDATE, DELETE')
  420.       return 1
  421.    end
  422.    if (@ObjType is null OR UPPER(@ObjType) not in (N'DATABASE', N'REPOSITORY', N'PUBLICATION'))
  423.    begin
  424.       raiserror(14266, -1, -1, N'@ObjType', N'DATABASE, REPOSITORY, PUBLICATION')
  425.       return 1
  426.    end
  427.    if (@ObjName is null)
  428.    begin
  429.       raiserror(14200, -1, -1, N'@ObjName')
  430.       return 1
  431.    end
  432.  
  433.    /* If publication object update or delete, we need GUID also */
  434.    if ((UPPER(@ObjType) in (N'PUBLICATION')) and UPPER(@Action) in (N'UPDATE', N'DELETE') and (@GUIDName is null))
  435.    begin
  436.       raiserror(14200, -1, -1, N'@GUIDNName')
  437.       return 1
  438.    end
  439.  
  440.    if (UPPER(@ObjType) in (N'PUBLICATION'))
  441.       select @dbname = @DatabaseName
  442.    else
  443.       select @dbname = @ObjName
  444.  
  445. -- Make sure the database exists
  446. --
  447.    if not exists (select * from master.dbo.sysdatabases where name = @dbname)
  448.    begin
  449.       raiserror(15010,-1,-1,@dbname)
  450.       return (1)
  451.    end
  452.  
  453.    /* Check permissions.  */
  454.    SELECT @cmd = 'USE ' + quotename(@dbname) + ' SELECT @isdbowner = is_member(''db_owner'')'
  455.  
  456.    EXEC @retcode = sp_executesql @cmd, N'@isdbowner int output', @isdbowner output
  457.    IF @@error <> 0 or @retcode <> 0
  458.       return 1
  459.  
  460.    IF (is_srvrolemember('sysadmin') <> 1 and isnull(@isdbowner, 0) <> 1)
  461.    BEGIN
  462.       raiserror(21050, 14, -1)
  463.       return 1
  464.    END
  465.  
  466.    /* common name length check */ 
  467.    if (UPPER(@ObjType) in (N'PUBLICATION'))
  468.        SELECT @commonname = @ObjName + N':' + @DatabaseName
  469.    else
  470.        SELECT @commonname = @ObjName
  471.   
  472.    IF (LEN(@commonname) > 64)
  473.       RAISERROR(14357, -1, -1, @commonname)
  474.        
  475.    select @Tmp = UPPER(@Action)
  476.    if (UPPER(@Tmp) like N'CRE%')
  477.       select @nAction = N'1'
  478.    else if (UPPER(@Tmp) like N'UPD%')
  479.       select @nAction = N'2'
  480.    else if (UPPER(@Tmp) like N'DEL%')
  481.       select @nAction = N'3'
  482.  
  483.    declare @nObjType nvarchar(3)
  484.    select @Tmp = UPPER(@ObjType)
  485.    if (UPPER(@Tmp) like N'DATAB%')
  486.       select @nObjType = N'2'
  487.    else if (UPPER(@Tmp) like N'REPOS%')
  488.       select @nObjType = N'3'
  489.    else if (UPPER(@Tmp) like N'PUBL%')
  490.       select @nObjType = N'4'
  491.  
  492.    /* are we running on Windows 2000 or NT4 SP5 with AD enabled?  continue only if TRUE */
  493.    EXECUTE @retval = master.dbo.xp_MSADEnabled
  494.    if (@retval = 0)
  495.    begin
  496.       /* prepare parameters */
  497.       declare @InstanceName sysname
  498.       declare @ServerName sysname
  499.       select @InstanceName = convert(sysname, serverproperty(N'InstanceName'))
  500.       select @ServerName = convert(sysname, serverproperty(N'ServerName'))
  501.       if (@InstanceName is NULL)
  502.          select @InstanceName = N'MSSQLSERVER'
  503.  
  504.       /* Need to create registry values only if create or update. */
  505.       if (@nAction <> N'3')
  506.       begin
  507.           EXECUTE @retval = master.dbo.xp_MSADSIObjReg @InstanceName, @nAction, @nObjType, @ObjName, @DatabaseName, @ServerName
  508.       end
  509.       if (@retval = 0)
  510.       begin
  511.          /* call xp with the valid parameters, xp_cmdshell expects double quote begin and end */
  512.          DECLARE @args NVARCHAR(512)
  513.          if ((@nObjType like N'4') and (@nAction like N'1'))
  514.          begin
  515.             /* PUBLICATION creation */
  516.             SELECT @args = @InstanceName + N' ' + @nAction +  N' ' + @nObjType + N' '  + quotename(@ObjName, N'"') + N' ' + quotename(@DatabaseName, N'"') 
  517.          end else if ((@nObjType like N'4') and (@nAction not like N'1'))
  518.          begin
  519.             /* PUBLICATION update or delete */
  520.             SELECT @args = @InstanceName + N' ' + @nAction +  N' ' + @nObjType + N' ' + quotename(@ObjName, N'"') + N' ' + quotename(@DatabaseName, N'"') + N' ' + @GUIDName
  521.          end else
  522.          begin
  523.             /* Non PUBLICATION objects */
  524.             SELECT @args = @InstanceName + N' ' + @nAction +  N' ' + @nObjType + N' ' + quotename(@ObjName, N'"')
  525.          end
  526.  
  527.          EXECUTE @retval = master.dbo.xp_adsirequest @args
  528.          if (@retval = 0)
  529.          begin
  530.             if (@nAction = N'3')
  531.             begin
  532.                 EXECUTE @retval = master.dbo.xp_MSADSIObjReg @InstanceName, @nAction, @nObjType, @ObjName, @DatabaseName, @ServerName
  533.                 if (@retval <> 0)
  534.                 begin
  535.                     raiserror(14303, -1, -1, N'sp_ActiveDirectory_Obj')
  536.                     return 1
  537.                 end
  538.             end
  539.          end
  540.          else
  541.          begin
  542.             if @retval = @SQLADSI_COM_ERROR 
  543.                 RAISERROR(14350, -1, -1)
  544.             else if @retval = @SQLADSI_UNEXP_ERROR 
  545.                 RAISERROR(14351, -1, -1)
  546.             else if @retval = @SQLADSI_SCP_NOT_FOUND 
  547.                 RAISERROR(14352, -1, -1)
  548.             else if @retval = @SQLADSI_SVC_ACCT_ERROR 
  549.                 RAISERROR(14353, -1, -1)
  550.             else if @retval = @SQLADSI_CANNOT_START_HLP 
  551.                 RAISERROR(14354, -1, -1)
  552.             else if @retval = @SQLADSI_TIMEOUT_WAIT_HLP 
  553.                 RAISERROR(14355, -1, -1)
  554.             else if @retval = @SQLADSI_AD_NOT_INSTALLED 
  555.                 RAISERROR(14356, -1, -1)
  556.             else if @retval = @SQLADSI_PROXY_ACCT_ERROR 
  557.                 RAISERROR(14358, -1, -1)
  558.    
  559.             /* Failed */
  560.             return 1
  561.          end
  562.       end else
  563.       begin
  564.          raiserror(14303, -1, -1, N'sp_ActiveDirectory_Obj')
  565.          return 1
  566.       end
  567.    end else
  568.    begin
  569.       raiserror(14304, -1, -1, N'sp_ActiveDirectory_Obj')
  570.       return 1
  571.    end
  572. end
  573. go
  574.  
  575. grant execute on sp_ActiveDirectory_Obj to public
  576. go
  577.  
  578. /**************************************************************/
  579. /* xp_GetAdminGroupName                                       */
  580. /**************************************************************/
  581. if exists (select * from sysobjects where name = N'xp_GetAdminGroupName' and type = N'X')
  582.     exec sp_dropextendedproc N'xp_GetAdminGroupName'
  583. go
  584.  
  585. print N''
  586. print N'Creating extended stored procedure xp_GetAdminGroupName...'
  587. go
  588.  
  589. exec sp_addextendedproc N'xp_GetAdminGroupName',N'xpstar.dll'
  590. go
  591.  
  592. grant execute on xp_GetAdminGroupName to public
  593. go
  594.  
  595. /**************************************************************/
  596. /* sp_ActiveDirectory_SCP                                     */
  597. /**************************************************************/
  598. if exists (select * from sysobjects where name = N'sp_ActiveDirectory_SCP' and type = N'P')
  599.     drop procedure sp_ActiveDirectory_SCP
  600. go
  601.  
  602. print N''
  603. print N'Creating procedure sp_ActiveDirectory_SCP...'
  604. go
  605.  
  606. create proc dbo.sp_ActiveDirectory_SCP
  607.     @Action  nvarchar(20) = N'create',    -- create_noupdate, create_with_db, create, update, delete, shutdown
  608.     @Startup int = 0                      -- 0 for non-startup, non-zero if called from server startup
  609. as
  610. begin
  611.    /* create_noupdate         : create the SCP object, if it exists already, update it.                                     */
  612.    /*                           create the DB objects only if they don't exists yet.  Do not update the existig DB objects. */
  613.    /* create_with_db          : create the SCP object, if it exsits already, update it.                                     */
  614.    /*                           Create all the DB objects under the SCP object.  If a DB object exists already, update it.  */
  615.    /* create (DEFAULT)        : create the SCP object, if it exists already, update it.                                     */
  616.    /* update                  : update the SCP object.                                                                      */
  617.    /* shutdown                : mark the SCP object to indicate not running, but don't delete it.                           */
  618.    /* delete                  : delete the SCP object and all the objects below it.                                         */
  619.  
  620.    SET NOCOUNT ON
  621.  
  622.    DECLARE @retval int
  623.    DECLARE @SQLADSI_COM_ERROR int
  624.    DECLARE @SQLADSI_UNEXP_ERROR int
  625.    DECLARE @SQLADSI_SCP_NOT_FOUND int
  626.    DECLARE @SQLADSI_SVC_ACCT_ERROR int
  627.    DECLARE @SQLADSI_CANNOT_START_HLP int
  628.    DECLARE @SQLADSI_TIMEOUT_WAIT_HLP int
  629.    DECLARE @SQLADSI_AD_NOT_INSTALLED int
  630.    DECLARE @SQLADSI_PROXY_ACCT_ERROR int
  631.  
  632.    SELECT @SQLADSI_COM_ERROR = 536870913
  633.    SELECT @SQLADSI_UNEXP_ERROR = 536870914
  634.    SELECT @SQLADSI_SCP_NOT_FOUND = 536870915
  635.    SELECT @SQLADSI_SVC_ACCT_ERROR = 536870916
  636.    SELECT @SQLADSI_CANNOT_START_HLP = 536870917
  637.    SELECT @SQLADSI_TIMEOUT_WAIT_HLP = 536870918
  638.    SELECT @SQLADSI_AD_NOT_INSTALLED = 536870919
  639.    SELECT @SQLADSI_PROXY_ACCT_ERROR = 536870920
  640.  
  641.    /* check permissions */
  642.    IF (not is_srvrolemember(N'sysadmin') = 1)
  643.    begin
  644.       raiserror(15003,-1,-1, N'sysadmin')
  645.       return 1
  646.    end
  647.  
  648.    /* check parameters */
  649.    if (@Action is null OR UPPER(@Action) not in (N'CREATE', N'UPDATE', N'DELETE', N'SHUTDOWN', N'CREATE_WITH_DB', N'CREATE_NOUPDATE'))
  650.    begin
  651.       raiserror(14266, -1, -1, N'@Action', N'CREATE, UPDATE, DELETE, SHUTDOWN, CREATE_WITH_DB, CREATE_NOUPDATE')
  652.       return 1
  653.    end
  654.  
  655.    declare @nAction nvarchar(3)
  656.    declare @Tmp nvarchar(10)
  657.    select @Tmp = UPPER(@Action)
  658.    if (UPPER(@Tmp) like N'CRE%')
  659.       select @nAction = N'1'
  660.    else if (UPPER(@Tmp) like N'UPD%')
  661.       select @nAction = N'2'
  662.    else if (UPPER(@Tmp) like N'DEL%')
  663.       select @nAction = N'3'
  664.    else if (UPPER(@Tmp) like N'SHU%')
  665.       select @nAction = N'4'
  666.  
  667.    /* are we running on Windows 2000 or NT4 SP5 with AD enabled?  continue only if TRUE */
  668.    EXECUTE @retval = master.dbo.xp_MSADEnabled
  669.    if (@retval = 0)
  670.    begin
  671.       /* Get the correct path for xpadsi.exe */
  672.       declare @Data nvarchar(256)
  673.       exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\Setup', N'SQLPath', @param = @Data OUT, @no_output = N'no_output'
  674.  
  675.       declare @BlankIndex int
  676.       select @BlankIndex = charindex(N' ', @Data)
  677.       if (@BlankIndex is NULL)
  678.           select @BlankIndex = 0
  679.  
  680.       /* Gather information */
  681.       declare @InstanceName sysname
  682.       declare @ServerName sysname
  683.       select @InstanceName = convert(sysname, serverproperty(N'InstanceName'))
  684.       select @ServerName = convert(sysname, serverproperty(N'ServerName'))
  685.       if (@InstanceName is NULL)
  686.          select @InstanceName = N'MSSQLSERVER'
  687.  
  688.       /* Need to create registry values only if create or update.  Delete registry when delete */
  689.       if (@nAction <> N'3')
  690.       begin
  691.           EXECUTE @retval = master.dbo.xp_MSADSIReg @InstanceName, @nAction, @ServerName
  692.       end
  693.       if (@retval = 0)
  694.       begin
  695.          /* call xp with the valid parameters */
  696.          DECLARE @command NVARCHAR(512)
  697.          DECLARE @nStartup NVARCHAR(5)
  698.          if (@Startup = 0)
  699.             select @nStartup = N'0'
  700.          else
  701.             select @nStartup = N'1'
  702.          if (@BlankIndex <> 0)
  703.             SELECT @command = N'""' + @Data + N'\Binn\' + N'xpadsi.exe' +  N'"" ' + @InstanceName + N' ' + @nAction +  N' 1 ' + @nStartup
  704.          else
  705.             SELECT @command = @Data + N'\Binn\' + N'xpadsi.exe ' + @InstanceName + N' ' + @nAction +  N' 1 ' + @nStartup
  706.  
  707.          EXECUTE @retval = master.dbo.xp_cmdshell @command
  708.          if (@retval = 0)
  709.          begin
  710.             /* we successfully delete the SCP and all its children,  let's remove the registry keys/values for them */
  711.             if (@nAction = N'3')
  712.             begin
  713.                 EXECUTE @retval = master.dbo.xp_MSADSIReg @InstanceName, @nAction, @ServerName
  714.                 if (@retval <> 0)
  715.                 begin
  716.                     raiserror(14303, -1, -1, N'sp_ActiveDirectory_SCP')
  717.                     return 1
  718.                 end
  719.             end
  720.             /* Get in only if caller asked for create with DB objects */
  721.             if (UPPER(@Action) like N'CREATE_WITH%') or (UPPER(@Action) like N'CREATE_NOU%')
  722.             begin
  723.                /* After we created the SCP object, we create all the database objects */
  724.  
  725.                /* Note that for performance reason, we want to create all the registry entries in one connection */
  726.                EXECUTE @retval = master.dbo.xp_MSADSIObjRegDB @InstanceName, @ServerName
  727.  
  728.                if (UPPER(@Action) like N'CREATE_WITH%')
  729.                begin
  730.                   declare hC cursor for select name from master.dbo.sysdatabases
  731.                end else begin
  732.                   declare hC cursor for select * from msdb.dbo.ADSINewDBs
  733.                end
  734.  
  735.                   declare @DBname sysname
  736.                   open hC
  737.                   fetch next from hC into @DBname
  738.  
  739.                   while (@@FETCH_STATUS = 0)
  740.                begin
  741.                   /* Do the AD part, continue even if we got error from one create */
  742.                   if (@BlankIndex <> 0)
  743.                      SELECT @command = N'""' + @Data + N'\Binn\' + N'xpadsi.exe ' + N'" ' + @InstanceName + N' 1 2 ' + N'"' + @DBname + N'""'
  744.                   else
  745.                      SELECT @command = @Data + N'\Binn\' + N'xpadsi.exe ' + @InstanceName + N' 1 2 ' + N'""' + @DBname + N'""'
  746.                   EXECUTE master.dbo.xp_cmdshell @command
  747.  
  748.                         fetch next from hC into @DBname
  749.                   end
  750.  
  751.                   close hC
  752.                   deallocate hC
  753.  
  754.                /* Get rid of the worker table, which was created by master.dbo.xp_MSADSIObjRegDB */
  755.                drop table msdb.dbo.ADSINewDBs
  756.             end
  757.             return 0
  758.          end else
  759.          begin
  760.             if @retval = @SQLADSI_COM_ERROR 
  761.                 RAISERROR(14350, -1, -1)
  762.             else if @retval = @SQLADSI_UNEXP_ERROR 
  763.                 RAISERROR(14351, -1, -1)
  764.             else if @retval = @SQLADSI_SCP_NOT_FOUND 
  765.                 RAISERROR(14352, -1, -1)
  766.             else if @retval = @SQLADSI_SVC_ACCT_ERROR 
  767.                 RAISERROR(14353, -1, -1)
  768.             else if @retval = @SQLADSI_CANNOT_START_HLP 
  769.                 RAISERROR(14354, -1, -1)
  770.             else if @retval = @SQLADSI_TIMEOUT_WAIT_HLP 
  771.                 RAISERROR(14355, -1, -1)
  772.             else if @retval = @SQLADSI_AD_NOT_INSTALLED 
  773.                 RAISERROR(14356, -1, -1)
  774.             else if @retval = @SQLADSI_PROXY_ACCT_ERROR 
  775.                 RAISERROR(14358, -1, -1)
  776.             /* Failed */
  777.             return 1
  778.          end
  779.       end else
  780.       begin
  781.          raiserror(14303, -1, -1, N'sp_ActiveDirectory_SCP')
  782.          return 1
  783.       end
  784.    end else
  785.    begin
  786.       raiserror(14359, -1, -1)
  787.       return 1
  788.    end
  789. end
  790. go
  791.  
  792. grant execute on sp_ActiveDirectory_SCP to public
  793. go
  794.  
  795. --------------------------------------------------------------------------------
  796. -- END XPSTAR SECTION
  797. --------------------------------------------------------------------------------
  798.  
  799. --------------------------------------------------------------------------------
  800. -- AGENT stored procedures added after release into instmsdb.sql file
  801. --
  802. -- sp_sqlagent_has_server_access
  803. -- sp_set_sqlagent_properties
  804. -- sp_verify_subsystem
  805. --------------------------------------------------------------------------------
  806.  
  807. use msdb
  808. go
  809.  
  810. /**************************************************************/
  811. /* SP_SQLAGENT_HAS_SERVER_ACCESS                              */
  812. /**************************************************************/
  813.  
  814. PRINT ''
  815. PRINT 'Creating procedure sp_sqlagent_has_server_access...'
  816. go
  817. IF (EXISTS (SELECT *
  818.             FROM msdb.dbo.sysobjects
  819.             WHERE (name = 'sp_sqlagent_has_server_access')
  820.               AND (type = 'P')))
  821.   DROP PROCEDURE sp_sqlagent_has_server_access
  822. go
  823. CREATE PROCEDURE sp_sqlagent_has_server_access
  824.   @login_name         sysname = NULL,
  825.   @is_sysadmin_member INT     = NULL OUTPUT
  826. AS
  827. BEGIN
  828.   DECLARE @has_server_access BIT
  829.   DECLARE @is_sysadmin       BIT
  830.   DECLARE @actual_login_name sysname
  831.   DECLARE @cachedate         DATETIME
  832.  
  833.   SET NOCOUNT ON
  834.  
  835.   SELECT @cachedate = NULL
  836.  
  837.   -- remove expired entries from the cache
  838.   DELETE msdb.dbo.syscachedcredentials
  839.   WHERE  DATEDIFF(MINUTE, cachedate, GETDATE()) >= 29
  840.  
  841.   -- query the cache
  842.   SELECT  @is_sysadmin = is_sysadmin_member,
  843.           @has_server_access = has_server_access,
  844.           @cachedate = cachedate
  845.   FROM    msdb.dbo.syscachedcredentials
  846.   WHERE   login_name = @login_name
  847.   AND     DATEDIFF(MINUTE, cachedate, GETDATE()) < 29
  848.  
  849.   IF (@cachedate IS NOT NULL)
  850.   BEGIN
  851.     -- no output variable
  852.     IF (@is_sysadmin_member IS NULL)
  853.     BEGIN
  854.       -- Return result row
  855.       SELECT has_server_access = @has_server_access,
  856.              is_sysadmin       = @is_sysadmin,
  857.              actual_login_name = @login_name
  858.       RETURN
  859.     END
  860.     ELSE
  861.     BEGIN
  862.       SELECT @is_sysadmin_member = @is_sysadmin
  863.       RETURN
  864.     END
  865.   END -- select from cache
  866.  
  867.   CREATE TABLE #xp_results
  868.   (
  869.   account_name      sysname      COLLATE database_default NOT NULL PRIMARY KEY,
  870.   type              NVARCHAR(10) COLLATE database_default NOT NULL,
  871.   privilege         NVARCHAR(10) COLLATE database_default NOT NULL,
  872.   mapped_login_name sysname      COLLATE database_default NOT NULL,
  873.   permission_path   sysname      COLLATE database_default NULL
  874.   )
  875.  
  876.   -- Set defaults
  877.   SELECT @has_server_access = 0
  878.   SELECT @is_sysadmin = 0
  879.   SELECT @actual_login_name = FORMATMESSAGE(14205)
  880.  
  881.   IF (@login_name IS NULL)
  882.   BEGIN
  883.     SELECT has_server_access = 1,
  884.            is_sysadmin       = IS_SRVROLEMEMBER(N'sysadmin'),
  885.            actual_login_name = SUSER_SNAME()
  886.     RETURN
  887.   END
  888.  
  889.   IF (@login_name LIKE '%\%')
  890.   BEGIN
  891.     -- Handle the LocalSystem account ('NT AUTHORITY\SYSTEM') as a special case
  892.     IF (UPPER(@login_name) = N'NT AUTHORITY\SYSTEM')
  893.     BEGIN
  894.       IF (EXISTS (SELECT *
  895.                   FROM master.dbo.syslogins
  896.                   WHERE (UPPER(loginname) = N'BUILTIN\ADMINISTRATORS')))
  897.       BEGIN
  898.         SELECT @has_server_access = hasaccess,
  899.                @is_sysadmin = sysadmin,
  900.                @actual_login_name = loginname
  901.         FROM master.dbo.syslogins
  902.         WHERE (UPPER(loginname) = N'BUILTIN\ADMINISTRATORS')
  903.       END
  904.     END
  905.     ELSE
  906.     BEGIN
  907.       -- Check if the NT login has been explicitly denied access
  908.       IF (EXISTS (SELECT *
  909.                   FROM master.dbo.syslogins
  910.                   WHERE (loginname = @login_name)
  911.                     AND (denylogin = 1)))
  912.       BEGIN
  913.         SELECT @has_server_access = 0,
  914.                @is_sysadmin = sysadmin,
  915.                @actual_login_name = loginname
  916.         FROM master.dbo.syslogins
  917.         WHERE (loginname = @login_name)
  918.       END
  919.       ELSE
  920.       BEGIN
  921.         -- Call xp_logininfo to determine server access
  922.         INSERT INTO #xp_results
  923.         EXECUTE master.dbo.xp_logininfo @login_name
  924.  
  925.         SELECT @has_server_access = CASE COUNT(*)
  926.                                       WHEN 0 THEN 0
  927.                                       ELSE 1
  928.                                     END
  929.         FROM #xp_results
  930.         SELECT @actual_login_name = mapped_login_name,
  931.                @is_sysadmin = CASE UPPER(privilege)
  932.                                 WHEN 'ADMIN' THEN 1
  933.                                 ELSE 0
  934.                              END
  935.         FROM #xp_results
  936.       END
  937.     END
  938.   END
  939.   ELSE
  940.   BEGIN
  941.     -- Standard login
  942.     IF (EXISTS (SELECT *
  943.                 FROM master.dbo.syslogins
  944.                 WHERE (loginname = @login_name)))
  945.     BEGIN
  946.       SELECT @has_server_access = hasaccess,
  947.              @is_sysadmin = sysadmin,
  948.              @actual_login_name = loginname
  949.       FROM master.dbo.syslogins
  950.       WHERE (loginname = @login_name)
  951.     END
  952.   END
  953.  
  954.   -- update the cache only if something is found
  955.   IF  (UPPER(@actual_login_name) <> '(UNKNOWN)')
  956.   BEGIN
  957.     BEGIN TRAN
  958.     IF EXISTS (SELECT * FROM msdb.dbo.syscachedcredentials WITH (TABLOCKX) WHERE login_name = @login_name)
  959.     BEGIN
  960.       UPDATE msdb.dbo.syscachedcredentials
  961.       SET    has_server_access = @has_server_access,
  962.              is_sysadmin_member = @is_sysadmin,
  963.              cachedate = GETDATE()
  964.       WHERE  login_name = @login_name
  965.     END
  966.     ELSE
  967.     BEGIN
  968.       INSERT INTO msdb.dbo.syscachedcredentials(login_name, has_server_access, is_sysadmin_member) 
  969.       VALUES(@login_name, @has_server_access, @is_sysadmin)
  970.     END
  971.     COMMIT TRAN
  972.   END
  973.  
  974.   IF (@is_sysadmin_member IS NULL)
  975.     -- Return result row
  976.     SELECT has_server_access = @has_server_access,
  977.            is_sysadmin       = @is_sysadmin,
  978.            actual_login_name = @actual_login_name
  979.   ELSE
  980.     -- output variable only
  981.     SELECT @is_sysadmin_member = @is_sysadmin
  982. END
  983. go
  984.  
  985.  
  986. /**************************************************************/
  987. /* sp_verify_subsystem                                        */
  988. /**************************************************************/
  989. PRINT N''
  990. PRINT N'Creating procedure sp_verify_subsystem...'
  991. go
  992.  
  993. IF (EXISTS (SELECT * FROM msdb.dbo.sysobjects WHERE (name = N'sp_verify_subsystem') AND (type = 'P')))
  994.   DROP PROCEDURE dbo.sp_verify_subsystem
  995. go
  996.  
  997. CREATE PROCEDURE dbo.sp_verify_subsystem
  998.   @subsystem NVARCHAR(40)
  999. AS
  1000. BEGIN
  1001.   SET NOCOUNT ON
  1002.  
  1003.   -- Remove any leading/trailing spaces from parameters
  1004.   SELECT @subsystem = LTRIM(RTRIM(@subsystem))
  1005.  
  1006.   -- NOTE: We don't use the results of sp_enum_sqlagent_subsystems for performance reasons
  1007.   IF (UPPER(@subsystem collate SQL_Latin1_General_CP1_CS_AS) IN 
  1008.                            (N'ACTIVESCRIPTING',
  1009.                             N'CMDEXEC',
  1010.                             N'DISTRIBUTION',
  1011.                             N'SNAPSHOT',
  1012.                             N'LOGREADER',
  1013.                             N'MERGE',
  1014.                             N'TSQL',
  1015.                             N'QUEUEREADER'))
  1016.     RETURN(0) -- Success
  1017.   ELSE
  1018.   BEGIN
  1019.     RAISERROR(14234, -1, -1, '@subsystem', 'sp_enum_sqlagent_subsystems')
  1020.     RETURN(1) -- Failure
  1021.   END
  1022. END
  1023. go
  1024.  
  1025. /**************************************************************/
  1026. /* SP_GET_SQLAGENT_PROPERTIES                                 */
  1027. /**************************************************************/
  1028.  
  1029. PRINT ''
  1030. PRINT 'Creating procedure sp_get_sqlagent_properties...'
  1031. go
  1032. IF (EXISTS (SELECT *
  1033.             FROM msdb.dbo.sysobjects
  1034.             WHERE (name = N'sp_get_sqlagent_properties')
  1035.               AND (type = 'P')))
  1036.   DROP PROCEDURE sp_get_sqlagent_properties
  1037. go
  1038. CREATE PROCEDURE sp_get_sqlagent_properties
  1039. AS
  1040. BEGIN
  1041.   DECLARE @auto_start                  INT
  1042.   DECLARE @startup_account             NVARCHAR(100)
  1043.   DECLARE @msx_server_name             NVARCHAR(30)
  1044.  
  1045.   -- Non-SQLDMO exposed properties
  1046.   DECLARE @sqlserver_restart           INT
  1047.   DECLARE @jobhistory_max_rows         INT
  1048.   DECLARE @jobhistory_max_rows_per_job INT
  1049.   DECLARE @errorlog_file               NVARCHAR(255)
  1050.   DECLARE @errorlogging_level          INT
  1051.   DECLARE @error_recipient             NVARCHAR(30)
  1052.   DECLARE @monitor_autostart           INT
  1053.   DECLARE @local_host_server           NVARCHAR(30)
  1054.   DECLARE @job_shutdown_timeout        INT
  1055.   DECLARE @cmdexec_account             VARBINARY(64)
  1056.   DECLARE @regular_connections         INT
  1057.   DECLARE @host_login_name             sysname
  1058.   DECLARE @host_login_password         VARBINARY(512)
  1059.   DECLARE @login_timeout               INT
  1060.   DECLARE @idle_cpu_percent            INT
  1061.   DECLARE @idle_cpu_duration           INT
  1062.   DECLARE @oem_errorlog                INT
  1063.   DECLARE @sysadmin_only               INT
  1064.   DECLARE @email_profile               NVARCHAR(64)
  1065.   DECLARE @email_save_in_sent_folder   INT
  1066.   DECLARE @cpu_poller_enabled          INT
  1067.  
  1068.   SET NOCOUNT ON
  1069.  
  1070.   -- NOTE: We return all SQLServerAgent properties at one go for performance reasons
  1071.  
  1072.   -- Read the values from the registry
  1073.   IF ((PLATFORM() & 0x1) = 0x1) -- NT
  1074.   BEGIN
  1075.     DECLARE @key NVARCHAR(200)
  1076.  
  1077.     SELECT @key = N'SYSTEM\CurrentControlSet\Services\'
  1078.     IF (SERVERPROPERTY('INSTANCENAME') IS NOT NULL)
  1079.       SELECT @key = @key + N'SQLAgent$' + CONVERT (sysname, SERVERPROPERTY('INSTANCENAME'))
  1080.     ELSE
  1081.       SELECT @key = @key + N'SQLServerAgent'
  1082.  
  1083.     EXECUTE master.dbo.xp_regread N'HKEY_LOCAL_MACHINE',
  1084.                                   @key,
  1085.                                   N'Start',
  1086.                                   @auto_start OUTPUT,
  1087.                                   N'no_output'
  1088.     EXECUTE master.dbo.xp_regread N'HKEY_LOCAL_MACHINE',
  1089.                                   @key,
  1090.                                   N'ObjectName',
  1091.                                   @startup_account OUTPUT,
  1092.                                   N'no_output'
  1093.   END
  1094.   ELSE
  1095.   BEGIN
  1096.     SELECT @auto_start = 3 -- Manual start
  1097.     SELECT @startup_account = NULL
  1098.   END
  1099.   EXECUTE master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE',
  1100.                                          N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1101.                                          N'MSXServerName',
  1102.                                          @msx_server_name OUTPUT,
  1103.                                          N'no_output'
  1104.  
  1105.   -- Non-SQLDMO exposed properties
  1106.   EXECUTE master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE',
  1107.                                          N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1108.                                          N'RestartSQLServer',
  1109.                                          @sqlserver_restart OUTPUT,
  1110.                                          N'no_output'
  1111.   EXECUTE master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE',
  1112.                                          N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1113.                                          N'JobHistoryMaxRows',
  1114.                                          @jobhistory_max_rows OUTPUT,
  1115.                                          N'no_output'
  1116.   EXECUTE master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE',
  1117.                                          N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1118.                                          N'JobHistoryMaxRowsPerJob',
  1119.                                          @jobhistory_max_rows_per_job OUTPUT,
  1120.                                          N'no_output'
  1121.   EXECUTE master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE',
  1122.                                          N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1123.                                          N'ErrorLogFile',
  1124.                                          @errorlog_file OUTPUT,
  1125.                                          N'no_output'
  1126.   EXECUTE master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE',
  1127.                                          N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1128.                                          N'ErrorLoggingLevel',
  1129.                                          @errorlogging_level OUTPUT,
  1130.                                          N'no_output'
  1131.   EXECUTE master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE',
  1132.                                          N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1133.                                          N'ErrorMonitor',
  1134.                                          @error_recipient OUTPUT,
  1135.                                          N'no_output'
  1136.   EXECUTE master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE',
  1137.                                          N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1138.                                          N'MonitorAutoStart',
  1139.                                          @monitor_autostart OUTPUT,
  1140.                                          N'no_output'
  1141.   EXECUTE master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE',
  1142.                                          N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1143.                                          N'ServerHost',
  1144.                                          @local_host_server OUTPUT,
  1145.                                          N'no_output'
  1146.   EXECUTE master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE',
  1147.                                          N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1148.                                          N'JobShutdownTimeout',
  1149.                                          @job_shutdown_timeout OUTPUT,
  1150.                                          N'no_output'
  1151.   EXECUTE master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE',
  1152.                                          N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1153.                                          N'CmdExecAccount',
  1154.                                          @cmdexec_account OUTPUT,
  1155.                                          N'no_output'
  1156.   EXECUTE master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE',
  1157.                                          N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1158.                                          N'RegularConnections',
  1159.                                          @regular_connections OUTPUT,
  1160.                                          N'no_output'
  1161.   DECLARE @OS int
  1162.   EXECUTE master.dbo.xp_MSplatform @OS OUTPUT
  1163.  
  1164.   IF (@OS = 2)
  1165.   EXECUTE master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE',
  1166.                                          N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1167.                                          N'HostLoginID',
  1168.                                          @host_login_name OUTPUT,
  1169.                                          N'no_output'
  1170.   ELSE
  1171.   EXECUTE master.dbo.xp_sqlagent_param   0, 
  1172.                                          N'HostLoginID',
  1173.                                          @host_login_name OUTPUT
  1174.  
  1175.    --check permissions
  1176.    IF (is_srvrolemember(N'sysadmin') = 1)
  1177.    begin
  1178.     IF (@OS = 2)
  1179.         EXECUTE master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE',
  1180.                                          N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1181.                                          N'HostPassword',
  1182.                                          @host_login_password OUTPUT,
  1183.                                          N'no_output'
  1184.     ELSE
  1185.         EXECUTE master.dbo.xp_sqlagent_param   0, 
  1186.                                          N'HostPassword',
  1187.                                          @host_login_password OUTPUT      
  1188.    end
  1189.    ELSE
  1190.        SELECT  @host_login_password = 0
  1191.  
  1192.   EXECUTE master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE',
  1193.                                          N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1194.                                          N'LoginTimeout',
  1195.                                          @login_timeout OUTPUT,
  1196.                                          N'no_output'
  1197.   EXECUTE master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE',
  1198.                                          N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1199.                                          N'IdleCPUPercent',
  1200.                                          @idle_cpu_percent OUTPUT,
  1201.                                          N'no_output'
  1202.   EXECUTE master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE',
  1203.                                          N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1204.                                          N'IdleCPUDuration',
  1205.                                          @idle_cpu_duration OUTPUT,
  1206.                                          N'no_output'
  1207.   EXECUTE master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE',
  1208.                                          N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1209.                                          N'OemErrorLog',
  1210.                                          @oem_errorlog OUTPUT,
  1211.                                          N'no_output'
  1212.   EXECUTE master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE',
  1213.                                          N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1214.                                          N'SysAdminOnly',
  1215.                                          @sysadmin_only OUTPUT,
  1216.                                          N'no_output'
  1217.   EXECUTE master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE',
  1218.                                          N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1219.                                          N'EmailProfile',
  1220.                                          @email_profile OUTPUT,
  1221.                                          N'no_output'
  1222.   EXECUTE master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE',
  1223.                                          N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1224.                                          N'EmailSaveSent',
  1225.                                          @email_save_in_sent_folder OUTPUT,
  1226.                                          N'no_output'
  1227.   EXECUTE master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE',
  1228.                                          N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1229.                                          N'CoreEngineMask',
  1230.                                          @cpu_poller_enabled OUTPUT,
  1231.                                          N'no_output'
  1232.   IF (@cpu_poller_enabled IS NOT NULL)
  1233.     SELECT @cpu_poller_enabled = CASE WHEN (@cpu_poller_enabled & 32) = 32 THEN 0 ELSE 1 END
  1234.  
  1235.   -- Return the values to the client
  1236.   SELECT auto_start = CASE @auto_start
  1237.                         WHEN 2 THEN 1 -- 2 means auto-start
  1238.                         WHEN 3 THEN 0 -- 3 means don't auto-start
  1239.                         ELSE 0        -- Safety net
  1240.                       END,
  1241.          msx_server_name = @msx_server_name,
  1242.          sqlagent_type = (SELECT CASE
  1243.                                     WHEN (COUNT(*) = 0) AND (ISNULL(DATALENGTH(@msx_server_name), 0) = 0) THEN 1 -- Standalone
  1244.                                     WHEN (COUNT(*) = 0) AND (ISNULL(DATALENGTH(@msx_server_name), 0) > 0) THEN 2 -- TSX
  1245.                                     WHEN (COUNT(*) > 0) AND (ISNULL(DATALENGTH(@msx_server_name), 0) = 0) THEN 3 -- MSX
  1246.                                     WHEN (COUNT(*) > 0) AND (ISNULL(DATALENGTH(@msx_server_name), 0) > 0) THEN 0 -- Multi-Level MSX (currently invalid)
  1247.                                     ELSE 0 -- Invalid
  1248.                                   END
  1249.                            FROM msdb.dbo.systargetservers),
  1250.          startup_account = @startup_account,
  1251.  
  1252.          -- Non-SQLDMO exposed properties
  1253.          sqlserver_restart = @sqlserver_restart,
  1254.          jobhistory_max_rows = @jobhistory_max_rows,
  1255.          jobhistory_max_rows_per_job = @jobhistory_max_rows_per_job,
  1256.          errorlog_file = @errorlog_file,
  1257.          errorlogging_level = ISNULL(@errorlogging_level, 7),
  1258.          error_recipient = @error_recipient,
  1259.          monitor_autostart = ISNULL(@monitor_autostart, 0),
  1260.          local_host_server = @local_host_server,
  1261.          job_shutdown_timeout = ISNULL(@job_shutdown_timeout, 15),
  1262.          cmdexec_account = @cmdexec_account,
  1263.          regular_connections = ISNULL(@regular_connections, 0),
  1264.          host_login_name = @host_login_name,
  1265.          host_login_password = @host_login_password,
  1266.          login_timeout = ISNULL(@login_timeout, 30),
  1267.          idle_cpu_percent = ISNULL(@idle_cpu_percent, 10),
  1268.          idle_cpu_duration = ISNULL(@idle_cpu_duration, 600),
  1269.          oem_errorlog = ISNULL(@oem_errorlog, 0),
  1270.          sysadmin_only = ISNULL(@sysadmin_only, 0),
  1271.          email_profile = @email_profile,
  1272.          email_save_in_sent_folder = ISNULL(@email_save_in_sent_folder, 0),
  1273.          cpu_poller_enabled = ISNULL(@cpu_poller_enabled, 0)
  1274. END
  1275. go
  1276.  
  1277. GRANT EXECUTE ON sp_get_sqlagent_properties  TO PUBLIC
  1278. go
  1279.  
  1280. /**************************************************************/
  1281. /* SP_SET_SQLAGENT_PROPERTIES                                 */
  1282. /**************************************************************/
  1283.  
  1284. ALTER PROCEDURE dbo.sp_set_sqlagent_properties
  1285.   @auto_start                  INT           = NULL, -- 1 or 0
  1286.   -- Non-SQLDMO exposed properties
  1287.   @sqlserver_restart           INT           = NULL, -- 1 or 0
  1288.   @jobhistory_max_rows         INT           = NULL, -- No maximum = -1, otherwise must be > 1
  1289.   @jobhistory_max_rows_per_job INT           = NULL, -- 1 to @jobhistory_max_rows
  1290.   @errorlog_file               NVARCHAR(255) = NULL, -- Full drive\path\name of errorlog file
  1291.   @errorlogging_level          INT           = NULL, -- 1 = error, 2 = warning, 4 = information
  1292.   @error_recipient             NVARCHAR(30)  = NULL, -- Network address of error popup recipient
  1293.   @monitor_autostart           INT           = NULL, -- 1 or 0
  1294.   @local_host_server           NVARCHAR(30)  = NULL, -- Alias of local host server
  1295.   @job_shutdown_timeout        INT           = NULL, -- 5 to 600 seconds
  1296.   @cmdexec_account             VARBINARY(64) = NULL, -- CmdExec account information
  1297.   @regular_connections         INT           = NULL, -- 1 or 0
  1298.   @host_login_name             sysname       = NULL, -- Login name (if regular_connections = 1)
  1299.   @host_login_password         VARBINARY(512) = NULL, -- Login password (if regular_connections = 1)
  1300.   @login_timeout               INT           = NULL, -- 5 to 45 (seconds)
  1301.   @idle_cpu_percent            INT           = NULL, -- 1 to 100
  1302.   @idle_cpu_duration           INT           = NULL, -- 20 to 86400 seconds
  1303.   @oem_errorlog                INT           = NULL, -- 1 or 0
  1304.   @sysadmin_only               INT           = NULL, -- 1 or 0
  1305.   @email_profile               NVARCHAR(64)  = NULL, -- Email profile name
  1306.   @email_save_in_sent_folder   INT           = NULL, -- 1 or 0
  1307.   @cpu_poller_enabled          INT           = NULL  -- 1 or 0
  1308. AS
  1309. BEGIN
  1310.   -- NOTE: We set all SQLServerAgent properties at one go for performance reasons.
  1311.   -- NOTE: You cannot set the value of the properties msx_server_name, is_msx or
  1312.   --       startup_account - they are all read only.
  1313.  
  1314.   DECLARE @res_valid_range           NVARCHAR(100)
  1315.   DECLARE @existing_core_engine_mask INT
  1316.  
  1317.   SET NOCOUNT ON
  1318.  
  1319.   -- Remove any leading/trailing spaces from parameters
  1320.   SELECT @errorlog_file     = LTRIM(RTRIM(@errorlog_file))
  1321.   SELECT @error_recipient   = LTRIM(RTRIM(@error_recipient))
  1322.   SELECT @local_host_server = LTRIM(RTRIM(@local_host_server))
  1323.   SELECT @host_login_name   = LTRIM(RTRIM(@host_login_name))
  1324.   SELECT @email_profile     = LTRIM(RTRIM(@email_profile))
  1325.  
  1326.   -- Make sure values (if supplied) are good
  1327.   IF (@auto_start IS NOT NULL)
  1328.   BEGIN
  1329.     -- NOTE: When setting the the services start value, 2 == auto-start, 3 == Don't auto-start
  1330.     SELECT @auto_start = CASE @auto_start
  1331.                            WHEN 0 THEN 3
  1332.                            WHEN 1 THEN 2
  1333.                            ELSE 3 -- Assume non auto-start if passed a junk value
  1334.                           END
  1335.   END
  1336.  
  1337.   -- Non-SQLDMO exposed properties
  1338.   IF ((@sqlserver_restart IS NOT NULL) AND (@sqlserver_restart <> 0))
  1339.     SELECT @sqlserver_restart = 1
  1340.  
  1341.   IF (@jobhistory_max_rows IS NOT NULL)
  1342.   BEGIN
  1343.     SELECT @res_valid_range = FORMATMESSAGE(14207)
  1344.     IF ((@jobhistory_max_rows < -1) OR (@jobhistory_max_rows = 0))
  1345.     BEGIN
  1346.       RAISERROR(14266, -1, -1, '@jobhistory_max_rows', @res_valid_range)
  1347.       RETURN(1) -- Failure
  1348.     END
  1349.   END
  1350.   ELSE
  1351.   BEGIN
  1352.     EXECUTE master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE',
  1353.                                            N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1354.                                            N'JobHistoryMaxRows',
  1355.                                            @jobhistory_max_rows OUTPUT,
  1356.                                            N'no_output'
  1357.     SELECT @jobhistory_max_rows = ISNULL(@jobhistory_max_rows, -1)
  1358.   END
  1359.  
  1360.   IF (@jobhistory_max_rows_per_job IS NOT NULL)
  1361.   BEGIN
  1362.     IF (@jobhistory_max_rows = -1)
  1363.       SELECT @jobhistory_max_rows_per_job = 0
  1364.     ELSE
  1365.     BEGIN
  1366.       IF ((@jobhistory_max_rows_per_job < 1) OR (@jobhistory_max_rows_per_job > @jobhistory_max_rows))
  1367.       BEGIN
  1368.         SELECT @res_valid_range = N'1..' + CONVERT(NVARCHAR, @jobhistory_max_rows)
  1369.         RAISERROR(14266, -1, -1, '@jobhistory_max_rows', @res_valid_range)
  1370.         RETURN(1) -- Failure
  1371.       END
  1372.     END
  1373.   END
  1374.  
  1375.   IF (@errorlogging_level IS NOT NULL) AND ((@errorlogging_level < 1) OR (@errorlogging_level > 7))
  1376.   BEGIN
  1377.     RAISERROR(14266, -1, -1, '@errorlogging_level', '1..7')
  1378.     RETURN(1) -- Failure
  1379.   END
  1380.  
  1381.   IF (@monitor_autostart IS NOT NULL) AND ((@monitor_autostart < 0) OR (@monitor_autostart > 1))
  1382.   BEGIN
  1383.     RAISERROR(14266, -1, -1, '@monitor_autostart', '0, 1')
  1384.     RETURN(1) -- Failure
  1385.   END
  1386.  
  1387.   IF (@job_shutdown_timeout IS NOT NULL) AND ((@job_shutdown_timeout < 5) OR (@job_shutdown_timeout > 600))
  1388.   BEGIN
  1389.     RAISERROR(14266, -1, -1, '@job_shutdown_timeout', '5..600')
  1390.     RETURN(1) -- Failure
  1391.   END
  1392.  
  1393.   IF (@regular_connections IS NOT NULL) AND ((@regular_connections < 0) OR (@regular_connections > 1))
  1394.   BEGIN
  1395.     RAISERROR(14266, -1, -1, '@regular_connections', '0, 1')
  1396.     RETURN(1) -- Failure
  1397.   END
  1398.  
  1399.   IF (@login_timeout IS NOT NULL) AND ((@login_timeout < 5) OR (@login_timeout > 45))
  1400.   BEGIN
  1401.     RAISERROR(14266, -1, -1, '@login_timeout', '5..45')
  1402.     RETURN(1) -- Failure
  1403.   END
  1404.  
  1405.   IF ((@idle_cpu_percent IS NOT NULL) AND ((@idle_cpu_percent < 1) OR (@idle_cpu_percent > 100)))
  1406.   BEGIN
  1407.     RAISERROR(14266, -1, -1, '@idle_cpu_percent', '10..100')
  1408.     RETURN(1) -- Failure
  1409.   END
  1410.  
  1411.   IF ((@idle_cpu_duration IS NOT NULL) AND ((@idle_cpu_duration < 20) OR (@idle_cpu_duration > 86400)))
  1412.   BEGIN
  1413.     RAISERROR(14266, -1, -1, '@idle_cpu_duration', '20..86400')
  1414.     RETURN(1) -- Failure
  1415.   END
  1416.  
  1417.   IF (@oem_errorlog IS NOT NULL) AND ((@oem_errorlog < 0) OR (@oem_errorlog > 1))
  1418.   BEGIN
  1419.     RAISERROR(14266, -1, -1, '@oem_errorlog', '0, 1')
  1420.     RETURN(1) -- Failure
  1421.   END
  1422.  
  1423.   IF (@sysadmin_only IS NOT NULL) AND ((@sysadmin_only < 0) OR (@sysadmin_only > 1))
  1424.   BEGIN
  1425.     RAISERROR(14266, -1, -1, '@sysadmin_only', '0, 1')
  1426.     RETURN(1) -- Failure
  1427.   END
  1428.  
  1429.   IF (@email_save_in_sent_folder IS NOT NULL) AND ((@email_save_in_sent_folder < 0) OR (@email_save_in_sent_folder > 1))
  1430.   BEGIN
  1431.     RAISERROR(14266, -1, -1, 'email_save_in_sent_folder', '0, 1')
  1432.     RETURN(1) -- Failure
  1433.   END
  1434.  
  1435.   IF (@cpu_poller_enabled IS NOT NULL) AND ((@cpu_poller_enabled < 0) OR (@cpu_poller_enabled > 1))
  1436.   BEGIN
  1437.     RAISERROR(14266, -1, -1, 'cpu_poller_enabled', '0, 1')
  1438.     RETURN(1) -- Failure
  1439.   END
  1440.  
  1441.   -- Write out the values
  1442.   IF (@auto_start IS NOT NULL)
  1443.   BEGIN
  1444.     IF ((PLATFORM() & 0x1) = 0x1) -- NT
  1445.     BEGIN
  1446.       DECLARE @key NVARCHAR(200)
  1447.  
  1448.       SELECT @key = N'SYSTEM\CurrentControlSet\Services\'
  1449.       IF (SERVERPROPERTY('INSTANCENAME') IS NOT NULL)
  1450.         SELECT @key = @key + N'SQLAgent$' + CONVERT (sysname, SERVERPROPERTY('INSTANCENAME'))
  1451.       ELSE
  1452.         SELECT @key = @key + N'SQLServerAgent'
  1453.  
  1454.       EXECUTE master.dbo.xp_regwrite N'HKEY_LOCAL_MACHINE',
  1455.                                      @key,
  1456.                                      N'Start',
  1457.                                      N'REG_DWORD',
  1458.                                      @auto_start
  1459.     END
  1460.     ELSE
  1461.       RAISERROR(14546, 16, 1, '@auto_start')
  1462.   END
  1463.  
  1464.   -- Non-SQLDMO exposed properties
  1465.   IF (@sqlserver_restart IS NOT NULL)
  1466.     EXECUTE master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE',
  1467.                                             N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1468.                                             N'RestartSQLServer',
  1469.                                             N'REG_DWORD',
  1470.                                             @sqlserver_restart
  1471.   IF (@jobhistory_max_rows IS NOT NULL)
  1472.     EXECUTE master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE',
  1473.                                             N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1474.                                             N'JobHistoryMaxRows',
  1475.                                             N'REG_DWORD',
  1476.                                             @jobhistory_max_rows
  1477.   IF (@jobhistory_max_rows_per_job IS NOT NULL)
  1478.     EXECUTE master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE',
  1479.                                             N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1480.                                             N'JobHistoryMaxRowsPerJob',
  1481.                                             N'REG_DWORD',
  1482.                                             @jobhistory_max_rows_per_job
  1483.   IF (@errorlog_file IS NOT NULL)
  1484.     EXECUTE master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE',
  1485.                                             N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1486.                                             N'ErrorLogFile',
  1487.                                             N'REG_SZ',
  1488.                                             @errorlog_file
  1489.   IF (@errorlogging_level IS NOT NULL)
  1490.     EXECUTE master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE',
  1491.                                             N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1492.                                             N'ErrorLoggingLevel',
  1493.                                             N'REG_DWORD',
  1494.                                             @errorlogging_level
  1495.   IF (@error_recipient IS NOT NULL)
  1496.     EXECUTE master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE',
  1497.                                             N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1498.                                             N'ErrorMonitor',
  1499.                                             N'REG_SZ',
  1500.                                             @error_recipient
  1501.   IF (@monitor_autostart IS NOT NULL)
  1502.     EXECUTE master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE',
  1503.                                             N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1504.                                             N'MonitorAutoStart',
  1505.                                             N'REG_DWORD',
  1506.                                             @monitor_autostart
  1507.   IF (@local_host_server IS NOT NULL)
  1508.     EXECUTE master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE',
  1509.                                             N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1510.                                             N'ServerHost',
  1511.                                             N'REG_SZ',
  1512.                                             @local_host_server
  1513.   IF (@job_shutdown_timeout IS NOT NULL)
  1514.     EXECUTE master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE',
  1515.                                             N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1516.                                             N'JobShutdownTimeout',
  1517.                                             N'REG_DWORD',
  1518.                                             @job_shutdown_timeout
  1519.   IF (@cmdexec_account IS NOT NULL)
  1520.     EXECUTE master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE',
  1521.                                             N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1522.                                             N'CmdExecAccount',
  1523.                                             N'REG_BINARY',
  1524.                                             @cmdexec_account
  1525.   IF (@regular_connections IS NOT NULL)
  1526.     EXECUTE master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE',
  1527.                                             N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1528.                                             N'RegularConnections',
  1529.                                             N'REG_DWORD',
  1530.                                             @regular_connections
  1531.  
  1532.   DECLARE @OS int
  1533.   EXECUTE master.dbo.xp_MSplatform @OS OUTPUT
  1534.  
  1535.   IF (@regular_connections = 0)
  1536.   BEGIN
  1537.     IF (@OS = 2)
  1538.     BEGIN
  1539.       EXECUTE master.dbo.xp_instance_regdeletevalue N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'HostLoginID'
  1540.       EXECUTE master.dbo.xp_instance_regdeletevalue N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'HostPassword'
  1541.     END
  1542.     ELSE
  1543.     BEGIN
  1544.       EXECUTE master.dbo.xp_sqlagent_param    2, N'HostLoginID'
  1545.       EXECUTE master.dbo.xp_sqlagent_param    2, N'HostPassword'
  1546.     END
  1547.   END
  1548.  
  1549.   IF (@host_login_name IS NOT NULL)
  1550.   BEGIN
  1551.     IF (@OS = 2)
  1552.     EXECUTE master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE',
  1553.                                             N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1554.                                             N'HostLoginID',
  1555.                                             N'REG_SZ',
  1556.                                             @host_login_name
  1557.     ELSE
  1558.     EXECUTE master.dbo.xp_sqlagent_param    1,
  1559.                                             N'HostLoginID',
  1560.                                             @host_login_name
  1561.   END
  1562.  
  1563.   IF (@host_login_password IS NOT NULL)
  1564.   BEGIN
  1565.     IF (@OS = 2)
  1566.     EXECUTE master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE',
  1567.                                             N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1568.                                             N'HostPassword',
  1569.                                             N'REG_BINARY',
  1570.                                             @host_login_password
  1571.     ELSE
  1572.     EXECUTE master.dbo.xp_sqlagent_param    1,
  1573.                                             N'HostPassword',
  1574.                                             @host_login_password
  1575.   END
  1576.  
  1577.   IF (@login_timeout IS NOT NULL)
  1578.     EXECUTE master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE',
  1579.                                             N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1580.                                             N'LoginTimeout',
  1581.                                             N'REG_DWORD',
  1582.                                             @login_timeout
  1583.   IF (@idle_cpu_percent IS NOT NULL)
  1584.     EXECUTE master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE',
  1585.                                             N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1586.                                             N'IdleCPUPercent',
  1587.                                             N'REG_DWORD',
  1588.                                             @idle_cpu_percent
  1589.   IF (@idle_cpu_duration IS NOT NULL)
  1590.     EXECUTE master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE',
  1591.                                             N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1592.                                             N'IdleCPUDuration',
  1593.                                             N'REG_DWORD',
  1594.                                             @idle_cpu_duration
  1595.   IF (@oem_errorlog IS NOT NULL)
  1596.     EXECUTE master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE',
  1597.                                             N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1598.                                             N'OemErrorLog',
  1599.                                             N'REG_DWORD',
  1600.                                             @oem_errorlog
  1601.   IF (@sysadmin_only IS NOT NULL)
  1602.     BEGIN
  1603.     IF (@sysadmin_only = 1)
  1604.       BEGIN
  1605.     EXECUTE master.dbo.xp_sqlagent_proxy_account N'DEL'
  1606.       END
  1607.     EXECUTE master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE',
  1608.                                             N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1609.                                             N'SysAdminOnly',
  1610.                                             N'REG_DWORD',
  1611.                                             @sysadmin_only
  1612.     END
  1613.  
  1614.   IF (@email_profile IS NOT NULL)
  1615.     EXECUTE master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE',
  1616.                                             N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1617.                                             N'EmailProfile',
  1618.                                             N'REG_SZ',
  1619.                                             @email_profile
  1620.   IF (@email_save_in_sent_folder IS NOT NULL)
  1621.     EXECUTE master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE',
  1622.                                             N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1623.                                             N'EmailSaveSent',
  1624.                                             N'REG_DWORD',
  1625.                                             @email_save_in_sent_folder
  1626.   IF (@cpu_poller_enabled IS NOT NULL)
  1627.   BEGIN
  1628.     EXECUTE master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE',
  1629.                                            N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1630.                                            N'CoreEngineMask',
  1631.                                            @existing_core_engine_mask OUTPUT,
  1632.                                            N'no_output'
  1633.     IF ((@existing_core_engine_mask IS NOT NULL) OR (@cpu_poller_enabled = 1))
  1634.     BEGIN
  1635.       IF (@cpu_poller_enabled = 1)
  1636.         SELECT @cpu_poller_enabled = (ISNULL(@existing_core_engine_mask, 0) & ~32)
  1637.       ELSE
  1638.         SELECT @cpu_poller_enabled = (ISNULL(@existing_core_engine_mask, 0) | 32)
  1639.  
  1640.       IF ((@existing_core_engine_mask IS NOT NULL) AND (@cpu_poller_enabled = 32))
  1641.         EXECUTE master.dbo.xp_instance_regdeletevalue N'HKEY_LOCAL_MACHINE',
  1642.                                                       N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1643.                                                       N'CoreEngineMask'
  1644.       ELSE
  1645.         EXECUTE master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE',
  1646.                                                 N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  1647.                                                 N'CoreEngineMask',
  1648.                                                 N'REG_DWORD',
  1649.                                                 @cpu_poller_enabled
  1650.     END
  1651.   END
  1652.  
  1653.   RETURN(0) -- Success
  1654. END
  1655.  
  1656. GO
  1657. SET QUOTED_IDENTIFIER OFF 
  1658. GO
  1659. SET ANSI_NULLS ON 
  1660. GO
  1661.  
  1662.  
  1663. /**************************************************************/
  1664. /* SP_SQLAGENT_GET_PERF_COUNTERS                              */
  1665. /**************************************************************/
  1666.  
  1667. PRINT ''
  1668. PRINT 'Creating procedure sp_sqlagent_get_perf_counters...'
  1669. go
  1670. IF (EXISTS (SELECT *
  1671.             FROM msdb.dbo.sysobjects
  1672.             WHERE (name = N'sp_sqlagent_get_perf_counters')
  1673.               AND (type = 'P')))
  1674.   DROP PROCEDURE sp_sqlagent_get_perf_counters
  1675. go
  1676.  
  1677. CREATE PROCEDURE sp_sqlagent_get_perf_counters
  1678.   @all_counters BIT = 0
  1679. AS
  1680. BEGIN
  1681.   SET NOCOUNT ON
  1682.  
  1683.   CREATE TABLE #temp
  1684.   (
  1685.   performance_condition NVARCHAR(1024) COLLATE database_default NOT NULL
  1686.   )
  1687.  
  1688.   INSERT INTO #temp VALUES (N'dummy')
  1689.  
  1690.   IF (@all_counters = 0)
  1691.   BEGIN
  1692.     INSERT INTO #temp
  1693.     SELECT DISTINCT SUBSTRING(performance_condition, 1, CHARINDEX('|', performance_condition, PATINDEX('%_|_%', performance_condition) + 2) - 1)
  1694.     FROM msdb.dbo.sysalerts
  1695.     WHERE (performance_condition IS NOT NULL)
  1696.       AND (enabled = 1)
  1697.   END
  1698.  
  1699.   SELECT 'object_name' = RTRIM(SUBSTRING(spi1.object_name, 1, 50)),
  1700.          'counter_name' = RTRIM(SUBSTRING(spi1.counter_name, 1, 50)),
  1701.          'instance_name' = CASE spi1.instance_name
  1702.                              WHEN N'' THEN NULL
  1703.                              ELSE RTRIM(spi1.instance_name)
  1704.                            END,
  1705.          'value' = CASE spi1.cntr_type
  1706.                      WHEN 537003008 -- A ratio
  1707.                        THEN CONVERT(FLOAT, spi1.cntr_value) / (SELECT CASE spi2.cntr_value WHEN 0 THEN 1 ELSE spi2.cntr_value END
  1708.                                                                FROM master.dbo.sysperfinfo spi2
  1709.                                                                WHERE (spi1.counter_name + ' ' = SUBSTRING(spi2.counter_name, 1, PATINDEX('% Base%', spi2.counter_name)))
  1710.                                                                  AND (spi1.instance_name = spi2.instance_name)
  1711.                                                                  AND (spi2.cntr_type = 1073939459))
  1712.                      ELSE spi1.cntr_value
  1713.                    END
  1714.   FROM master.dbo.sysperfinfo spi1,
  1715.        #temp tmp
  1716.   WHERE (spi1.cntr_type <> 1073939459) -- Divisors
  1717.     AND ((@all_counters = 1) OR
  1718.          (tmp.performance_condition = RTRIM(spi1.object_name) + '|' + RTRIM(spi1.counter_name)))
  1719. END
  1720. go
  1721.  
  1722.  
  1723. use msdb
  1724. go
  1725.  
  1726. /**************************************************************/
  1727. /* sp_post_msx_operation                                      */
  1728. /**************************************************************/
  1729. PRINT ''
  1730. PRINT 'Creating procedure sp_post_msx_operation'
  1731. go
  1732. IF (EXISTS (SELECT *
  1733.             FROM msdb.dbo.sysobjects
  1734.             WHERE (name = 'sp_post_msx_operation')
  1735.               AND (type = 'P')))
  1736.   DROP PROCEDURE sp_post_msx_operation
  1737. go
  1738. CREATE PROCEDURE sp_post_msx_operation
  1739.   @operation              VARCHAR(64),
  1740.   @object_type            VARCHAR(64)      = 'JOB',
  1741.   @job_id                 UNIQUEIDENTIFIER = NULL, -- NOTE: 0x00 means 'ALL'
  1742.   @specific_target_server NVARCHAR(30)     = NULL,
  1743.   @value                  INT              = NULL  -- For polling interval value
  1744. AS
  1745. BEGIN
  1746.   DECLARE @operation_code            INT
  1747.   DECLARE @specific_target_server_id INT
  1748.   DECLARE @instructions_posted       INT
  1749.   DECLARE @job_id_as_char            VARCHAR(36)
  1750.   DECLARE @msx_time_zone_adjustment  INT
  1751.   DECLARE @local_machine_name        NVARCHAR(30)
  1752.   DECLARE @retval                    INT
  1753.  
  1754.   SET NOCOUNT ON
  1755.  
  1756.   -- Remove any leading/trailing spaces from parameters
  1757.   SELECT @operation              = LTRIM(RTRIM(@operation))
  1758.   SELECT @object_type            = LTRIM(RTRIM(@object_type))
  1759.   SELECT @specific_target_server = LTRIM(RTRIM(@specific_target_server))
  1760.  
  1761.   -- Turn [nullable] empty string parameters into NULLs
  1762.   IF (@specific_target_server = N'') SELECT @specific_target_server = NULL
  1763.  
  1764.   -- Only a sysadmin can do this, but fail silently for a non-sysadmin
  1765.   IF (ISNULL(IS_SRVROLEMEMBER(N'sysadmin'), 0) <> 1)
  1766.     RETURN(0) -- Success (or more accurately a no-op)
  1767.  
  1768.   -- Check operation
  1769.   SELECT @operation = UPPER(@operation)
  1770.   SELECT @operation_code = CASE @operation
  1771.                              WHEN 'INSERT'    THEN 1
  1772.                              WHEN 'UPDATE'    THEN 2
  1773.                              WHEN 'DELETE'    THEN 3
  1774.                              WHEN 'START'     THEN 4
  1775.                              WHEN 'STOP'      THEN 5
  1776.                              WHEN 'RE-ENLIST' THEN 6
  1777.                              WHEN 'DEFECT'    THEN 7
  1778.                              WHEN 'SYNC-TIME' THEN 8
  1779.                              WHEN 'SET-POLL'  THEN 9
  1780.                              ELSE 0
  1781.                            END
  1782.   IF (@operation_code = 0)
  1783.   BEGIN
  1784.     RAISERROR(14266, -1, -1, '@operation_code', 'INSERT, UPDATE, DELETE, START, STOP, RE-ENLIST, DEFECT, SYNC-TIME, SET-POLL')
  1785.     RETURN(1) -- Failure
  1786.   END
  1787.  
  1788.   -- Check object type (in 7.0 only 'JOB' or 'SERVER' are valid)
  1789.   IF ((@object_type <> 'JOB') AND (@object_type <> 'SERVER'))
  1790.   BEGIN
  1791.     RAISERROR(14266, -1, -1, '@object_type', 'JOB, SERVER')
  1792.     RETURN(1) -- Failure
  1793.   END
  1794.  
  1795.   -- Check that for a object type of JOB a job_id has been supplied
  1796.   IF ((@object_type = 'JOB') AND (@job_id IS NULL))
  1797.   BEGIN
  1798.     RAISERROR(14233, -1, -1)
  1799.     RETURN(1) -- Failure
  1800.   END
  1801.  
  1802.   -- Check polling interval value
  1803.   IF (@operation_code = 9) AND ((ISNULL(@value, 0) < 10) OR (ISNULL(@value, 0) > 28800))
  1804.   BEGIN
  1805.     RAISERROR(14266, -1, -1, '@value', '10..28800')
  1806.     RETURN(1) -- Failure
  1807.   END
  1808.  
  1809.   -- Check specific target server
  1810.   IF (@specific_target_server IS NOT NULL)
  1811.   BEGIN
  1812.     -- Check if the local server is being targeted
  1813.     IF (UPPER(@specific_target_server) = UPPER(CONVERT(NVARCHAR(30), SERVERPROPERTY('ServerName'))))
  1814.     BEGIN
  1815.       RETURN(0)
  1816.     END
  1817.     ELSE
  1818.     BEGIN
  1819.       SELECT @specific_target_server_id = server_id
  1820.       FROM msdb.dbo.systargetservers
  1821.       WHERE (server_name = @specific_target_server)
  1822.       IF (@specific_target_server_id IS NULL)
  1823.       BEGIN
  1824.         RAISERROR(14262, -1, -1, '@specific_target_server', @specific_target_server)
  1825.         RETURN(1) -- Failure
  1826.       END
  1827.     END
  1828.   END
  1829.  
  1830.   -- Check that this server is an MSX server
  1831.   IF ((SELECT COUNT(*)
  1832.        FROM msdb.dbo.systargetservers) = 0)
  1833.   BEGIN
  1834.     RETURN(0)
  1835.   END
  1836.  
  1837.   -- Get local machine name
  1838.   EXECUTE @retval = master.dbo.xp_getnetname @local_machine_name OUTPUT
  1839.   IF (@retval <> 0) OR (@local_machine_name IS NULL)
  1840.   BEGIN
  1841.     RAISERROR(14225, -1, -1)
  1842.     RETURN(1)
  1843.   END
  1844.  
  1845.   CREATE TABLE #target_servers (server_name sysname COLLATE database_default NOT NULL)
  1846.  
  1847.   -- Optimization: Simply update the date-posted if the operation has already been posted (but
  1848.   -- not yet downloaded) and the target server is not currently polling...
  1849.   IF ((@object_type = 'JOB')    AND (ISNULL(@job_id, 0x00) <> CONVERT(UNIQUEIDENTIFIER, 0x00)) AND (@operation_code IN (1, 2, 3, 4, 5))) OR -- Any JOB operation
  1850.      ((@object_type = 'SERVER') AND (@operation_code IN (6, 7))) -- RE-ENLIST or DEFECT operations
  1851.   BEGIN
  1852.     -- Populate the list of target servers to post to
  1853.     IF (@specific_target_server IS NOT NULL)
  1854.       INSERT INTO #target_servers VALUES (@specific_target_server)
  1855.     ELSE
  1856.     BEGIN
  1857.       IF (@object_type = 'SERVER')
  1858.         INSERT INTO #target_servers
  1859.         SELECT server_name
  1860.         FROM msdb.dbo.systargetservers
  1861.  
  1862.       IF (@object_type = 'JOB')
  1863.         INSERT INTO #target_servers
  1864.         SELECT sts.server_name
  1865.         FROM msdb.dbo.sysjobs_view     sjv,
  1866.              msdb.dbo.sysjobservers    sjs,
  1867.              msdb.dbo.systargetservers sts
  1868.         WHERE (sjv.job_id = @job_id)
  1869.           AND (sjv.job_id = sjs.job_id)
  1870.           AND (sjs.server_id = sts.server_id)
  1871.           AND (sjs.server_id <> 0)
  1872.     END
  1873.   END
  1874.  
  1875.   -- Job-specific processing...
  1876.   IF (@object_type = 'JOB')
  1877.   BEGIN
  1878.     -- Validate the job (if supplied)
  1879.     IF (@job_id <> CONVERT(UNIQUEIDENTIFIER, 0x00))
  1880.     BEGIN
  1881.       SELECT @job_id_as_char = CONVERT(VARCHAR(36), @job_id)
  1882.  
  1883.       -- Check if the job exists
  1884.       IF (NOT EXISTS (SELECT *
  1885.                       FROM msdb.dbo.sysjobs_view
  1886.                       WHERE (job_id = @job_id)))
  1887.       BEGIN
  1888.         RAISERROR(14262, -1, -1, '@job_id', @job_id_as_char)
  1889.         RETURN(1) -- Failure
  1890.       END
  1891.  
  1892.       -- If this is a local job then there's nothing for us to do
  1893.       IF (EXISTS (SELECT *
  1894.                   FROM msdb.dbo.sysjobservers
  1895.                   WHERE (job_id = @job_id)
  1896.                     AND (server_id = 0))) -- 0 means local server
  1897.       OR (NOT EXISTS (SELECT *
  1898.                       FROM msdb.dbo.sysjobservers
  1899.                       WHERE (job_id = @job_id)))
  1900.       BEGIN
  1901.         RETURN(0)
  1902.       END
  1903.     END
  1904.  
  1905.     -- Generate the sysdownloadlist row(s)...
  1906.     IF (@operation_code = 1) OR  -- Insert
  1907.        (@operation_code = 2) OR  -- Update
  1908.        (@operation_code = 3) OR  -- Delete
  1909.        (@operation_code = 4) OR  -- Start
  1910.        (@operation_code = 5)     -- Stop
  1911.     BEGIN
  1912.       IF (@job_id = CONVERT(UNIQUEIDENTIFIER, 0x00)) -- IE. 'ALL'
  1913.       BEGIN
  1914.         -- All jobs
  1915.  
  1916.         -- Handle DELETE as a special case (rather than posting 1 instruction per job we just
  1917.         -- post a single instruction that means 'delete all jobs from the MSX')
  1918.         IF (@operation_code = 3)
  1919.         BEGIN
  1920.           INSERT INTO msdb.dbo.sysdownloadlist
  1921.                 (source_server,
  1922.                  operation_code,
  1923.                  object_type,
  1924.                  object_id,
  1925.                  target_server)
  1926.           SELECT @local_machine_name,
  1927.                  @operation_code,
  1928.                  1,                -- 1 means 'JOB'
  1929.                  CONVERT(UNIQUEIDENTIFIER, 0x00),
  1930.                  sts.server_name
  1931.           FROM systargetservers sts
  1932.           WHERE ((@specific_target_server_id IS NULL) OR (sts.server_id = @specific_target_server_id))
  1933.             AND ((SELECT COUNT(*)
  1934.                   FROM msdb.dbo.sysjobservers
  1935.                   WHERE (server_id = sts.server_id)) > 0)
  1936.           SELECT @instructions_posted = @@rowcount
  1937.         END
  1938.         ELSE
  1939.         BEGIN
  1940.           INSERT INTO msdb.dbo.sysdownloadlist
  1941.                 (source_server,
  1942.                  operation_code,
  1943.                  object_type,
  1944.                  object_id,
  1945.                  target_server)
  1946.           SELECT @local_machine_name,
  1947.                  @operation_code,
  1948.                  1,                -- 1 means 'JOB'
  1949.                  sjv.job_id,
  1950.                  sts.server_name
  1951.           FROM sysjobs_view     sjv,
  1952.                sysjobservers    sjs,
  1953.                systargetservers sts
  1954.           WHERE (sjv.job_id = sjs.job_id)
  1955.             AND (sjs.server_id = sts.server_id)
  1956.             AND (sjs.server_id <> 0) -- We want to exclude local jobs
  1957.             AND ((@specific_target_server_id IS NULL) OR (sjs.server_id = @specific_target_server_id))
  1958.           SELECT @instructions_posted = @@rowcount
  1959.         END
  1960.       END
  1961.       ELSE
  1962.       BEGIN
  1963.         -- Specific job (ie. @job_id is not 0x00)
  1964.         INSERT INTO msdb.dbo.sysdownloadlist
  1965.               (source_server,
  1966.                operation_code,
  1967.                object_type,
  1968.                object_id,
  1969.                target_server,
  1970.                deleted_object_name)
  1971.         SELECT @local_machine_name,
  1972.                @operation_code,
  1973.                1,                -- 1 means 'JOB'
  1974.                sjv.job_id,
  1975.                sts.server_name,
  1976.                CASE @operation_code WHEN 3 -- Delete
  1977.                                       THEN sjv.name
  1978.                                       ELSE NULL
  1979.                                     END
  1980.         FROM sysjobs_view     sjv,
  1981.              sysjobservers    sjs,
  1982.              systargetservers sts
  1983.         WHERE (sjv.job_id = @job_id)
  1984.           AND (sjv.job_id = sjs.job_id)
  1985.           AND (sjs.server_id = sts.server_id)
  1986.           AND (sjs.server_id <> 0) -- We want to exclude local jobs
  1987.           AND ((@specific_target_server_id IS NULL) OR (sjs.server_id = @specific_target_server_id))
  1988.         SELECT @instructions_posted = @@rowcount
  1989.       END
  1990.     END
  1991.     ELSE
  1992.     BEGIN
  1993.       RAISERROR(14266, -1, -1, '@operation_code', 'INSERT, UPDATE, DELETE, START, STOP')
  1994.       RETURN(1) -- Failure
  1995.     END
  1996.   END
  1997.  
  1998.   -- Server-specific processing...
  1999.   IF (@object_type = 'SERVER')
  2000.   BEGIN
  2001.     -- Generate the sysdownloadlist row(s)...
  2002.     IF (@operation_code = 6) OR  -- ReEnlist
  2003.        (@operation_code = 7) OR  -- Defect
  2004.        (@operation_code = 8) OR  -- Synchronize time (with MSX)
  2005.        (@operation_code = 9)     -- Set MSX polling interval (in seconds)
  2006.     BEGIN
  2007.       IF (@operation_code = 8)
  2008.       BEGIN
  2009.         EXECUTE master.dbo.xp_regread N'HKEY_LOCAL_MACHINE',
  2010.                                       N'SYSTEM\CurrentControlSet\Control\TimeZoneInformation',
  2011.                                       N'Bias',
  2012.                                       @msx_time_zone_adjustment OUTPUT,
  2013.                                       N'no_output'
  2014.         SELECT @msx_time_zone_adjustment = -ISNULL(@msx_time_zone_adjustment, 0)
  2015.       END
  2016.  
  2017.       INSERT INTO msdb.dbo.sysdownloadlist
  2018.             (source_server,
  2019.              operation_code,
  2020.              object_type,
  2021.              object_id,
  2022.              target_server)
  2023.       SELECT @local_machine_name,
  2024.              @operation_code,
  2025.              2,                  -- 2 means 'SERVER'
  2026.              CASE @operation_code
  2027.                WHEN 8 THEN CONVERT(UNIQUEIDENTIFIER, CONVERT(BINARY(16), -(@msx_time_zone_adjustment - sts.time_zone_adjustment)))
  2028.                WHEN 9 THEN CONVERT(UNIQUEIDENTIFIER, CONVERT(BINARY(16), @value))
  2029.                ELSE CONVERT(UNIQUEIDENTIFIER, 0x00)
  2030.              END,
  2031.              sts.server_name
  2032.       FROM systargetservers sts
  2033.       WHERE ((@specific_target_server_id IS NULL) OR (sts.server_id = @specific_target_server_id))
  2034.       SELECT @instructions_posted = @@rowcount
  2035.     END
  2036.     ELSE
  2037.     BEGIN
  2038.       RAISERROR(14266, -1, -1, '@operation_code', 'RE-ENLIST, DEFECT, SYNC-TIME, SET-POLL')
  2039.       RETURN(1) -- Failure
  2040.     END
  2041.   END
  2042.  
  2043.  
  2044.   -- Report number of rows inserted
  2045.   IF (@object_type = 'JOB') AND
  2046.      (@job_id = CONVERT(UNIQUEIDENTIFIER, 0x00)) AND
  2047.      (@instructions_posted = 0) AND
  2048.      (@specific_target_server_id IS NOT NULL)
  2049.     RAISERROR(14231, 0, 1, '@specific_target_server', @specific_target_server)
  2050.   ELSE
  2051.     RAISERROR(14230, 0, 1, @instructions_posted, @operation)
  2052.  
  2053.   -- Delete any [downloaded] instructions that are over the registry-defined limit
  2054.   IF (@specific_target_server IS NOT NULL)
  2055.     EXECUTE msdb.dbo.sp_downloaded_row_limiter @specific_target_server
  2056.  
  2057.   RETURN(0) -- 0 means success
  2058. END
  2059. go
  2060.  
  2061. GRANT EXECUTE ON sp_post_msx_operation TO PUBLIC
  2062. GO
  2063.  
  2064.  
  2065. use msdb
  2066. go
  2067. /**************************************************************/
  2068. /* SP_DELETE_TARGETSERVER                                     */
  2069. /**************************************************************/
  2070. PRINT ''
  2071. PRINT 'Creating procedure sp_delete_targetserver'
  2072. go
  2073. IF (EXISTS (SELECT *
  2074.             FROM msdb.dbo.sysobjects
  2075.             WHERE (name = N'sp_delete_targetserver')
  2076.               AND (type = 'P')))
  2077.   DROP PROCEDURE sp_delete_targetserver
  2078. go
  2079. CREATE PROCEDURE sp_delete_targetserver
  2080.   @server_name        NVARCHAR(30),
  2081.   @clear_downloadlist BIT = 1,
  2082.   @post_defection     BIT = 1
  2083. AS
  2084. BEGIN
  2085.   DECLARE @server_id INT
  2086.   DECLARE @tsx_probe NVARCHAR(50)
  2087.  
  2088.   SET NOCOUNT ON
  2089.  
  2090.   -- Remove any leading/trailing spaces from parameters
  2091.   SELECT @server_name = LTRIM(RTRIM(@server_name))
  2092.  
  2093.   -- Check server name
  2094.   SELECT @server_id = server_id
  2095.   FROM msdb.dbo.systargetservers
  2096.   WHERE (server_name = @server_name)
  2097.  
  2098.   IF (@server_id IS NULL)
  2099.   BEGIN
  2100.     RAISERROR(14262, -1, -1, '@server_name', @server_name)
  2101.     RETURN(1) -- Failure
  2102.   END
  2103.  
  2104.   BEGIN TRANSACTION
  2105.  
  2106.     IF (@clear_downloadlist = 1)
  2107.     BEGIN
  2108.       DELETE FROM msdb.dbo.sysdownloadlist
  2109.       WHERE (target_server = @server_name)
  2110.     END
  2111.  
  2112.     IF (@post_defection = 1)
  2113.     BEGIN
  2114.       -- Post a defect instruction to the server
  2115.       -- NOTE: We must do this BEFORE deleting the systargetservers row
  2116.       EXECUTE msdb.dbo.sp_post_msx_operation 'DEFECT', 'SERVER', 0x00, @server_name
  2117.     END
  2118.  
  2119.     DELETE FROM msdb.dbo.systargetservers
  2120.     WHERE (server_id = @server_id)
  2121.  
  2122.     DELETE FROM msdb.dbo.systargetservergroupmembers
  2123.     WHERE (server_id = @server_id)
  2124.  
  2125.     DELETE FROM msdb.dbo.sysjobservers
  2126.     WHERE (server_id = @server_id)
  2127.  
  2128.   COMMIT TRANSACTION
  2129.  
  2130.   RETURN(@@error) -- 0 means success
  2131. END
  2132. go
  2133.  
  2134.  
  2135. use msdb
  2136. go
  2137.  
  2138. /**************************************************************/
  2139. /* SP_MSX_ENLIST                                              */
  2140. /**************************************************************/
  2141.  
  2142. PRINT ''
  2143. PRINT 'Creating procedure sp_msx_enlist...'
  2144. go
  2145. IF (EXISTS (SELECT *
  2146.             FROM msdb.dbo.sysobjects
  2147.             WHERE (name = 'sp_msx_enlist')
  2148.               AND (type = 'P')))
  2149.   DROP PROCEDURE sp_msx_enlist
  2150. go
  2151. CREATE PROCEDURE sp_msx_enlist
  2152.   @msx_server_name NVARCHAR(30),
  2153.   @location        NVARCHAR(100) = NULL, -- The procedure will supply a default
  2154.   @ping_server     BIT = 1               -- Set to 0 to skip the MSX ping test
  2155. AS
  2156. BEGIN
  2157.   DECLARE @current_msx_server   NVARCHAR(30)
  2158.   DECLARE @local_machine_name   NVARCHAR(30)
  2159.   DECLARE @retval               INT
  2160.   DECLARE @time_zone_adjustment INT
  2161.   DECLARE @local_time           NVARCHAR(100)
  2162.   DECLARE @nt_user              NVARCHAR(100)
  2163.   DECLARE @poll_interval        INT
  2164.  
  2165.   SET NOCOUNT ON
  2166.  
  2167.   -- Only a sysadmin can do this
  2168.   IF (ISNULL(IS_SRVROLEMEMBER(N'sysadmin'), 0) <> 1)
  2169.   BEGIN
  2170.     RAISERROR(15003, 16, 1, N'sysadmin')
  2171.     RETURN(1) -- Failure
  2172.   END
  2173.  
  2174.   -- Only an NT server can be enlisted
  2175.   IF ((PLATFORM() & 0x1) <> 0x1) -- NT
  2176.   BEGIN
  2177.     RAISERROR(14540, -1, 1)
  2178.     RETURN(1) -- Failure
  2179.   END
  2180.  
  2181.   -- Only SBS, Standard, or Enterprise editions of SQL Server can be enlisted
  2182.   IF ((PLATFORM() & 0x100) = 0x100) -- Desktop package
  2183.   BEGIN
  2184.     RAISERROR(14539, -1, -1)
  2185.     RETURN(1) -- Failure
  2186.   END
  2187.  
  2188.   -- Remove any leading/trailing spaces from parameters
  2189.   SELECT @msx_server_name = LTRIM(RTRIM(@msx_server_name))
  2190.   SELECT @location        = LTRIM(RTRIM(@location))
  2191.  
  2192.   -- Turn [nullable] empty string parameters into NULLs
  2193.   IF (@location = N'') SELECT @location = NULL
  2194.  
  2195.   -- Change to MSX server name to upper-case since it's a machine name
  2196. --  SELECT @msx_server_name = UPPER(@msx_server_name)
  2197.  
  2198.   SELECT @retval = 0
  2199.  
  2200.   -- Get the values that we'll need for the [re]enlistment operation (except the local time
  2201.   -- which we get right before we call xp_msx_enlist to that it's as accurate as possible)
  2202.   SELECT @nt_user = ISNULL(NT_CLIENT(), ISNULL(SUSER_SNAME(), FORMATMESSAGE(14205)))
  2203.   EXECUTE master.dbo.xp_regread N'HKEY_LOCAL_MACHINE',
  2204.                                 N'SYSTEM\CurrentControlSet\Control\TimeZoneInformation',
  2205.                                 N'Bias',
  2206.                                 @time_zone_adjustment OUTPUT,
  2207.                                 N'no_output'
  2208.   IF ((PLATFORM() & 0x1) = 0x1) -- NT
  2209.     SELECT @time_zone_adjustment = -ISNULL(@time_zone_adjustment, 0)
  2210.   ELSE
  2211.     SELECT @time_zone_adjustment = -CONVERT(INT, CONVERT(BINARY(2), ISNULL(@time_zone_adjustment, 0)))
  2212.  
  2213.   EXECUTE master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE',
  2214.                                          N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  2215.                                          N'MSXPollInterval',
  2216.                                          @poll_interval OUTPUT,
  2217.                                          N'no_output'
  2218.   SELECT @poll_interval = ISNULL(@poll_interval, 60) -- This should be the same as DEF_REG_MSX_POLL_INTERVAL
  2219.   EXECUTE master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE',
  2220.                                          N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  2221.                                          N'MSXServerName',
  2222.                                          @current_msx_server OUTPUT,
  2223.                                          N'no_output'
  2224.   SELECT @current_msx_server = LTRIM(RTRIM(@current_msx_server))
  2225.   
  2226.   -- Check if this machine is an MSX (and therefore cannot be enlisted into another MSX)
  2227.   IF (EXISTS (SELECT *
  2228.               FROM msdb.dbo.systargetservers))
  2229.   BEGIN
  2230.     --Get local server/instance name
  2231.     SELECT @local_machine_name = UPPER(CONVERT(NVARCHAR(30), SERVERPROPERTY('ServerName')))
  2232.     
  2233.     RAISERROR(14299, -1, -1, @local_machine_name)
  2234.     RETURN(1) -- Failure
  2235.   END
  2236.  
  2237.   -- Check if the MSX supplied is the same as the local machine (this is not allowed)
  2238. /*  IF (UPPER(@local_machine_name) = UPPER(@msx_server_name))
  2239.   BEGIN
  2240.     RAISERROR(14297, -1, -1)
  2241.     RETURN(1) -- Failure
  2242.   END*/
  2243.  
  2244.   -- Check if MSDB has be re-installed since we enlisted
  2245.   IF (@current_msx_server IS NOT NULL) AND
  2246.      (NOT EXISTS (SELECT *
  2247.                   FROM msdb.dbo.sqlagent_info
  2248.                   WHERE (attribute = 'DateEnlisted')))
  2249.   BEGIN
  2250.     -- User is tring to [re]enlist after a re-install, so we have to forcefully defect before
  2251.     -- we can fully enlist again
  2252.     EXECUTE msdb.dbo.sp_msx_defect @forced_defection = 1
  2253.     SELECT @current_msx_server = NULL
  2254.   END
  2255.  
  2256.   -- Check if we are already enlisted, in which case we re-enlist
  2257.   IF ((@current_msx_server IS NOT NULL) AND (@current_msx_server <> N''))
  2258.   BEGIN
  2259.     IF (UPPER(@current_msx_server) = UPPER(@msx_server_name))
  2260.     BEGIN
  2261.       -- Update the [existing] enlistment
  2262.       SELECT @local_time = CONVERT(NVARCHAR, GETDATE(), 112) + N' ' + CONVERT(NVARCHAR, GETDATE(), 108)
  2263.       EXECUTE @retval = master.dbo.xp_msx_enlist 2, @msx_server_name, @nt_user, @location, @time_zone_adjustment, @local_time, @poll_interval
  2264.       RETURN(@retval) -- 0 means success
  2265.     END
  2266.     ELSE
  2267.     BEGIN
  2268.       RAISERROR(14296, -1, -1, @current_msx_server)
  2269.       RETURN(1) -- Failure
  2270.     END
  2271.   END
  2272.  
  2273.   -- If we get this far then we're dealing with a new enlistment...
  2274.  
  2275.   -- Check if the MSX supplied exists on the network
  2276.  
  2277.   IF (@ping_server = 1)
  2278.   BEGIN
  2279.     DECLARE @msx_machine_name NVARCHAR (30)
  2280.     DECLARE @char_index       INT
  2281.  
  2282.     SELECT @char_index = CHARINDEX (N'\', @msx_server_name)
  2283.     IF (@char_index > 0)
  2284.     BEGIN
  2285.       SELECT @msx_machine_name = LEFT (@msx_server_name, @char_index - 1)
  2286.     END
  2287.     ELSE
  2288.     BEGIN
  2289.       SELECT @msx_machine_name = @msx_server_name
  2290.     END
  2291.  
  2292.     IF ((PLATFORM() & 0x2) = 0x2) -- Win9x
  2293.     BEGIN
  2294.       EXECUTE(N'CREATE TABLE #output (output NVARCHAR(1024) COLLATE database_default)
  2295.                 SET NOCOUNT ON
  2296.                 INSERT INTO #output
  2297.                 EXECUTE master.dbo.xp_cmdshell N''net view \\' + @msx_machine_name + N'''
  2298.                 IF (EXISTS (SELECT *
  2299.                             FROM #output
  2300.                             WHERE (output LIKE N''% 53%'')))
  2301.                    RAISERROR(14262, -1, -1, N''@msx_server_name'', N''' + @msx_machine_name + N''') WITH SETERROR')
  2302.       IF (@@error <> 0)
  2303.         RETURN(1) -- Failure
  2304.     END
  2305.     ELSE
  2306.     BEGIN
  2307.       EXECUTE(N'DECLARE @retval INT
  2308.                 SET NOCOUNT ON
  2309.                 EXECUTE @retval = master.dbo.xp_cmdshell N''net view \\' + @msx_machine_name + N' > nul'', no_output
  2310.                 IF (@retval <> 0)
  2311.                   RAISERROR(14262, -1, -1, N''@msx_server_name'', N''' + @msx_machine_name + N''') WITH SETERROR')
  2312.       IF (@@error <> 0)
  2313.         RETURN(1) -- Failure
  2314.     END
  2315.   END
  2316.  
  2317.   -- If no location is supplied, generate one (such as we can)
  2318.   IF (@location IS NULL)
  2319.     EXECUTE msdb.dbo.sp_generate_server_description @location OUTPUT
  2320.  
  2321.   SELECT @local_time = CONVERT(NVARCHAR, GETDATE(), 112) + ' ' + CONVERT(NVARCHAR, GETDATE(), 108)
  2322.   EXECUTE @retval = master.dbo.xp_msx_enlist 0, @msx_server_name, @nt_user, @location, @time_zone_adjustment, @local_time, @poll_interval
  2323.  
  2324.   IF (@retval = 0)
  2325.   BEGIN
  2326.     EXECUTE master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE',
  2327.                                             N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
  2328.                                             N'MSXServerName',
  2329.                                             N'REG_SZ',
  2330.                                             @msx_server_name
  2331.  
  2332.     IF (@current_msx_server IS NOT NULL)
  2333.       RAISERROR(14228, 0, 1, @current_msx_server, @msx_server_name)
  2334.     ELSE
  2335.       RAISERROR(14229, 0, 1, @msx_server_name)
  2336.  
  2337.     -- Add entry to sqlagent_info
  2338.     INSERT INTO msdb.dbo.sqlagent_info (attribute, value) VALUES ('DateEnlisted', CONVERT(VARCHAR(10), GETDATE(), 112))
  2339.   END
  2340.  
  2341.   RETURN(@retval) -- 0 means success
  2342. END
  2343. go
  2344.  
  2345.  
  2346. use msdb
  2347. go
  2348.  
  2349. /**************************************************************/
  2350. /* SP_ENLIST_TSX                                              */
  2351. /**************************************************************/
  2352. PRINT ''
  2353. PRINT 'Creating procedure sp_enlist_tsx' 
  2354. go
  2355.  
  2356. IF EXISTS (SELECT name FROM sysobjects 
  2357.          WHERE name = 'sp_enlist_tsx' AND type = 'P')
  2358.    DROP PROCEDURE sp_enlist_tsx
  2359. GO
  2360.  
  2361. print N'Creating stored procedure sp_enlist_tsx'
  2362. go
  2363. create proc sp_enlist_tsx
  2364.     @Action int,            -- 0 - enlist; 1 - defect; 2 - update
  2365.     @ServerName  nvarchar(30),    -- tsx server name
  2366.     @Location  nvarchar(200),    -- tsx server location
  2367.     @TimeZoneAdjustment int,    -- tsx server time zone adjustment
  2368.     @LocalTime datetime,        -- tsx server local time
  2369.     @NTUserName nvarchar(100),    -- name of the user performing the enlistment
  2370.     @PollInterval int        -- polling interval
  2371. as
  2372. begin
  2373.    SET NOCOUNT ON
  2374.  
  2375.    /* check permissions */
  2376.    IF (not is_srvrolemember(N'TargetServerRole') = 1)
  2377.    begin
  2378.     raiserror(15003,-1,-1, N'TargetServerRole')
  2379.     return 1
  2380.    end
  2381.  
  2382.    /* check input parameters */
  2383.    if @ServerName is null
  2384.    begin
  2385.     raiserror(14043, -1, -1, '@ServerName')
  2386.     return 2
  2387.    end
  2388.  
  2389.    select @ServerName = LTRIM(@ServerName)
  2390.    select @ServerName = RTRIM(@ServerName)
  2391.    if @ServerName = ''
  2392.    begin
  2393.     raiserror(21263, -1, -1, '@ServerName')
  2394.     return 3
  2395.    end
  2396.  
  2397.    if @Action <> 1 And @Action <> 2
  2398.    begin
  2399.     /* default action is to enlist */
  2400.     select @Action = 0
  2401.    end
  2402.  
  2403.   if @Action = 0 /* enlisting */
  2404.   begin
  2405.     /* check input parameters */
  2406.     if @NTUserName is null
  2407.     begin
  2408.        raiserror(14043, -1, -1, '@NTUserName')
  2409.        return 4
  2410.     end
  2411.  
  2412.     select @NTUserName = LTRIM(@NTUserName)
  2413.     select @NTUserName = RTRIM(@NTUserName)
  2414.     if @NTUserName = ''
  2415.     begin
  2416.       raiserror(21263, -1, -1, '@NTUserName')
  2417.       return 5
  2418.     end
  2419.  
  2420.     /* check if local server is already configured as TSX machine */
  2421.     declare @msx_server_name NVARCHAR(128)
  2422.     select @msx_server_name = N''
  2423.  
  2424.     execute master.dbo.xp_instance_regread 
  2425.         N'HKEY_LOCAL_MACHINE',
  2426.         N'Software\Microsoft\MSSQLServer\SQLServerAgent',
  2427.         N'MSXServerName',
  2428.         @msx_server_name OUTPUT
  2429.  
  2430.     select @msx_server_name = LTRIM(@msx_server_name)
  2431.     select @msx_server_name = RTRIM(@msx_server_name)
  2432.     if @msx_server_name <> N''
  2433.     begin
  2434.        raiserror(14360, -1, -1, @@SERVERNAME)
  2435.        return 6
  2436.     end
  2437.  
  2438.     /* 
  2439.     * check that local server is not running a desktop SKU, 
  2440.     * i.e. Win9x, Office, or MSDE
  2441.     */
  2442.     if( PLATFORM() & 0x100 = 0x100 )
  2443.     begin
  2444.        raiserror(14362, -1, -1)
  2445.        return 8
  2446.     end
  2447.  
  2448.     /* check if we have any MSXOperators defined */
  2449.     if not exists (SELECT * FROM msdb.dbo.sysoperators WHERE name = N'MSXOperator')
  2450.     begin
  2451.        raiserror(14363, -1, -1)
  2452.        return 9
  2453.     end
  2454.  
  2455.     /* all checks have passed, insert new row into systargetservers table */
  2456.     INSERT INTO msdb.dbo.systargetservers 
  2457.     (
  2458.     server_name, 
  2459.     location, 
  2460.     time_zone_adjustment, 
  2461.     enlist_date, 
  2462.     last_poll_date, 
  2463.     status, 
  2464.     local_time_at_last_poll, 
  2465.     enlisted_by_nt_user, 
  2466.     poll_interval
  2467.     ) 
  2468.     VALUES 
  2469.     (
  2470.     @ServerName, 
  2471.     @Location, 
  2472.     @TimeZoneAdjustment, 
  2473.     GETDATE(), 
  2474.     GETDATE(), 
  2475.     1, 
  2476.     @LocalTime, 
  2477.     @NTUserName, 
  2478.     @PollInterval
  2479.     )
  2480.  
  2481.     /* delete hanging rows from sysdownloadlist */
  2482.     DELETE FROM msdb.dbo.sysdownloadlist 
  2483.     WHERE target_server = @ServerName
  2484.    end
  2485.  
  2486.    if @Action = 2 /* updating existing enlistment */
  2487.    begin
  2488.     /* check if we have any MSXOperators defined */
  2489.     if not exists (SELECT * FROM msdb.dbo.sysoperators WHERE name = N'MSXOperator')
  2490.     begin
  2491.        raiserror(14363, -1, -1)
  2492.        return 10
  2493.     end
  2494.  
  2495.     /* check if TSX machine is already enlisted */
  2496.     If not exists (SELECT * FROM msdb.dbo.systargetservers WHERE server_name =@ServerName)
  2497.     begin
  2498.        raiserror(14364, -1, -1)
  2499.        return 11
  2500.     end
  2501.  
  2502.     if @Location is null /* don't update the location if it is not supplied */
  2503.     begin
  2504.         UPDATE msdb.dbo.systargetservers SET 
  2505.         time_zone_adjustment = @TimeZoneAdjustment, 
  2506.         poll_interval = @PollInterval
  2507.         WHERE (server_name = @ServerName)
  2508.     end
  2509.     else
  2510.     begin
  2511.         UPDATE msdb.dbo.systargetservers SET 
  2512.         location = @Location, 
  2513.         time_zone_adjustment = @TimeZoneAdjustment, 
  2514.         poll_interval = @PollInterval
  2515.         WHERE (server_name = @ServerName)
  2516.     end
  2517.    end
  2518.  
  2519.   if @Action = 1 /* defecting */
  2520.   begin
  2521.     if (exists (SELECT * FROM msdb.dbo.systargetservers WHERE server_name = @ServerName)) 
  2522.     begin
  2523.         execute msdb.dbo.sp_delete_targetserver 
  2524.             @server_name = @ServerName, 
  2525.             @post_defection = 0 
  2526.     end
  2527.     else
  2528.     begin
  2529.         DELETE FROM msdb.dbo.sysdownloadlist 
  2530.         WHERE (target_server = @ServerName)
  2531.     end
  2532.   end
  2533.  
  2534.   if @Action = 0 Or @Action = 2 /* enlisting or updating existing enlistment */
  2535.   begin
  2536.     /* select resultset to return to the caller */
  2537.     SELECT 
  2538.     id,
  2539.     name, 
  2540.     enabled, 
  2541.     email_address, 
  2542.     pager_address, 
  2543.     netsend_address, 
  2544.     weekday_pager_start_time, 
  2545.     weekday_pager_end_time, 
  2546.     saturday_pager_start_time, 
  2547.     saturday_pager_end_time, 
  2548.     sunday_pager_start_time, 
  2549.     sunday_pager_end_time, 
  2550.     pager_days 
  2551.     FROM 
  2552.     msdb.dbo.sysoperators WHERE (name = N'MSXOperator')
  2553.    end
  2554. end
  2555. go
  2556.  
  2557. grant execute on sp_enlist_tsx to public
  2558. go
  2559.  
  2560. /**************************************************************/
  2561. /* SP_ADD_JOBSTEP_INTERNAL                                    */
  2562. /**************************************************************/
  2563.  
  2564. PRINT ''
  2565. PRINT 'Creating procedure sp_add_jobstep_internal...'
  2566. go
  2567. IF (EXISTS (SELECT *
  2568.             FROM msdb.dbo.sysobjects
  2569.             WHERE (name = N'sp_add_jobstep_internal')
  2570.               AND (type = 'P')))
  2571.   DROP PROCEDURE dbo.sp_add_jobstep_internal
  2572. go
  2573. CREATE PROCEDURE dbo.sp_add_jobstep_internal
  2574.   @job_id                UNIQUEIDENTIFIER = NULL,   -- Must provide either this or job_name
  2575.   @job_name              sysname          = NULL,   -- Must provide either this or job_id
  2576.   @step_id               INT              = NULL,   -- The proc assigns a default
  2577.   @step_name             sysname,
  2578.   @subsystem             NVARCHAR(40)     = N'TSQL',
  2579.   @command               NVARCHAR(3201)   = NULL,   -- We declare this as NVARCHAR(3201) not NVARCHAR(3200) so that we can catch 'silent truncation' of commands
  2580.   @additional_parameters NTEXT            = NULL,
  2581.   @cmdexec_success_code  INT              = 0,
  2582.   @on_success_action     TINYINT          = 1,      -- 1 = Quit With Success, 2 = Quit With Failure, 3 = Goto Next Step, 4 = Goto Step
  2583.   @on_success_step_id    INT              = 0,
  2584.   @on_fail_action        TINYINT          = 2,      -- 1 = Quit With Success, 2 = Quit With Failure, 3 = Goto Next Step, 4 = Goto Step
  2585.   @on_fail_step_id       INT              = 0,
  2586.   @server                NVARCHAR(30)      = NULL,
  2587.   @database_name         sysname          = NULL,
  2588.   @database_user_name    sysname          = NULL,
  2589.   @retry_attempts        INT              = 0,      -- No retries
  2590.   @retry_interval        INT              = 0,      -- 0 minute interval
  2591.   @os_run_priority       INT              = 0,      -- -15 = Idle, -1 = Below Normal, 0 = Normal, 1 = Above Normal, 15 = Time Critical)
  2592.   @output_file_name      NVARCHAR(200)    = NULL,
  2593.   @flags                 INT              = 0       -- 0 = Normal, 1 = Encrypted command (read only), 2 = Append output files (if any), 4 = Write TSQL step output to step history
  2594. AS
  2595. BEGIN
  2596.   DECLARE @retval      INT
  2597.   DECLARE @max_step_id INT
  2598.  
  2599.   SET NOCOUNT ON
  2600.  
  2601.   -- Remove any leading/trailing spaces from parameters
  2602.   SELECT @step_name          = LTRIM(RTRIM(@step_name))
  2603.   SELECT @subsystem          = LTRIM(RTRIM(@subsystem))
  2604.   SELECT @server             = LTRIM(RTRIM(@server))
  2605.   SELECT @database_name      = LTRIM(RTRIM(@database_name))
  2606.   SELECT @database_user_name = LTRIM(RTRIM(@database_user_name))
  2607.   SELECT @output_file_name   = LTRIM(RTRIM(@output_file_name))
  2608.  
  2609.   -- Turn [nullable] empty string parameters into NULLs
  2610.   IF (@server             = N'') SELECT @server             = NULL
  2611.   IF (@database_name      = N'') SELECT @database_name      = NULL
  2612.   IF (@database_user_name = N'') SELECT @database_user_name = NULL
  2613.   IF (@output_file_name   = N'') SELECT @output_file_name   = NULL
  2614.  
  2615.   -- Check authority (only SQLServerAgent can add a step to a non-local job)
  2616.   EXECUTE @retval = sp_verify_jobproc_caller @job_id = @job_id, @program_name = N'SQLAgent%'
  2617.   IF (@retval <> 0)
  2618.     RETURN(@retval)
  2619.  
  2620.   EXECUTE @retval = sp_verify_job_identifiers '@job_name',
  2621.                                               '@job_id',
  2622.                                                @job_name OUTPUT,
  2623.                                                @job_id   OUTPUT
  2624.   IF (@retval <> 0)
  2625.     RETURN(1) -- Failure
  2626.  
  2627.   -- Default step id (if not supplied)
  2628.   IF (@step_id IS NULL)
  2629.   BEGIN
  2630.     SELECT @step_id = ISNULL(MAX(step_id), 0) + 1
  2631.     FROM msdb.dbo.sysjobsteps
  2632.     WHERE (job_id = @job_id)
  2633.   END
  2634.  
  2635.   -- Check parameters
  2636.   EXECUTE @retval = sp_verify_jobstep @job_id,
  2637.                                       @step_id,
  2638.                                       @step_name,
  2639.                                       @subsystem,
  2640.                                       @command,
  2641.                                       @server,
  2642.                                       @on_success_action,
  2643.                                       @on_success_step_id,
  2644.                                       @on_fail_action,
  2645.                                       @on_fail_step_id,
  2646.                                       @os_run_priority,
  2647.                                       @database_name      OUTPUT,
  2648.                                       @database_user_name OUTPUT,
  2649.                                       @flags,
  2650.                                       @output_file_name
  2651.   IF (@retval <> 0)
  2652.     RETURN(1) -- Failure
  2653.  
  2654.   -- Get current maximum step id
  2655.   SELECT @max_step_id = ISNULL(MAX(step_id), 0)
  2656.   FROM msdb.dbo.sysjobsteps
  2657.   WHERE (job_id = @job_id)
  2658.  
  2659.   BEGIN TRANSACTION
  2660.  
  2661.     -- Update the job's version/last-modified information
  2662.     UPDATE msdb.dbo.sysjobs
  2663.     SET version_number = version_number + 1,
  2664.         date_modified = GETDATE()
  2665.     WHERE (job_id = @job_id)
  2666.  
  2667.     -- Adjust step id's (unless the new step is being inserted at the 'end')
  2668.     -- NOTE: We MUST do this before inserting the step.
  2669.     IF (@step_id <= @max_step_id)
  2670.     BEGIN
  2671.       UPDATE msdb.dbo.sysjobsteps
  2672.       SET step_id = step_id + 1
  2673.       WHERE (step_id >= @step_id)
  2674.         AND (job_id = @job_id)
  2675.  
  2676.       -- Clean up OnSuccess/OnFail references
  2677.       UPDATE msdb.dbo.sysjobsteps
  2678.       SET on_success_step_id = on_success_step_id + 1
  2679.       WHERE (on_success_step_id >= @step_id)
  2680.         AND (job_id = @job_id)
  2681.  
  2682.       UPDATE msdb.dbo.sysjobsteps
  2683.       SET on_fail_step_id = on_fail_step_id + 1
  2684.       WHERE (on_fail_step_id >= @step_id)
  2685.         AND (job_id = @job_id)
  2686.  
  2687.       UPDATE msdb.dbo.sysjobsteps
  2688.       SET on_success_step_id = 0,
  2689.           on_success_action = 1  -- Quit With Success
  2690.       WHERE (on_success_step_id = @step_id)
  2691.         AND (job_id = @job_id)
  2692.  
  2693.       UPDATE msdb.dbo.sysjobsteps
  2694.       SET on_fail_step_id = 0,
  2695.           on_fail_action = 2     -- Quit With Failure
  2696.       WHERE (on_fail_step_id = @step_id)
  2697.         AND (job_id = @job_id)
  2698.     END
  2699.  
  2700.     -- Insert the step
  2701.     INSERT INTO msdb.dbo.sysjobsteps
  2702.            (job_id,
  2703.             step_id,
  2704.             step_name,
  2705.             subsystem,
  2706.             command,
  2707.             flags,
  2708.             additional_parameters,
  2709.             cmdexec_success_code,
  2710.             on_success_action,
  2711.             on_success_step_id,
  2712.             on_fail_action,
  2713.             on_fail_step_id,
  2714.             server,
  2715.             database_name,
  2716.             database_user_name,
  2717.             retry_attempts,
  2718.             retry_interval,
  2719.             os_run_priority,
  2720.             output_file_name,
  2721.             last_run_outcome,
  2722.             last_run_duration,
  2723.             last_run_retries,
  2724.             last_run_date,
  2725.             last_run_time)
  2726.     VALUES (@job_id,
  2727.             @step_id,
  2728.             @step_name,
  2729.             @subsystem,
  2730.             @command,
  2731.             @flags,
  2732.             @additional_parameters,
  2733.             @cmdexec_success_code,
  2734.             @on_success_action,
  2735.             @on_success_step_id,
  2736.             @on_fail_action,
  2737.             @on_fail_step_id,
  2738.             @server,
  2739.             @database_name,
  2740.             @database_user_name,
  2741.             @retry_attempts,
  2742.             @retry_interval,
  2743.             @os_run_priority,
  2744.             @output_file_name,
  2745.             0,
  2746.             0,
  2747.             0,
  2748.             0,
  2749.             0)
  2750.  
  2751.   COMMIT TRANSACTION
  2752.  
  2753.   -- Make sure that SQLServerAgent refreshes the job if the 'Has Steps' property has changed
  2754.   IF ((SELECT COUNT(*)
  2755.        FROM msdb.dbo.sysjobsteps
  2756.        WHERE (job_id = @job_id)) = 1)
  2757.   BEGIN
  2758.     -- NOTE: We only notify SQLServerAgent if we know the job has been cached
  2759.     IF (EXISTS (SELECT *
  2760.                 FROM msdb.dbo.sysjobservers
  2761.                 WHERE (job_id = @job_id)
  2762.                   AND (server_id = 0)))
  2763.       EXECUTE msdb.dbo.sp_sqlagent_notify @op_type       = N'J',
  2764.                                             @job_id      = @job_id,
  2765.                                             @action_type = N'U'
  2766.   END
  2767.  
  2768.   -- For a multi-server job, remind the user that they need to call sp_post_msx_operation
  2769.   IF (EXISTS (SELECT *
  2770.               FROM msdb.dbo.sysjobservers
  2771.               WHERE (job_id = @job_id)
  2772.                 AND (server_id <> 0)))
  2773.     RAISERROR(14547, 0, 1, N'INSERT', N'sp_post_msx_operation')
  2774.  
  2775.   RETURN(0) -- Success
  2776. END
  2777. go
  2778.  
  2779. /**************************************************************/
  2780. /* SP_ADD_JOBSTEP                                             */
  2781. /**************************************************************/
  2782.  
  2783. PRINT ''
  2784. PRINT 'Creating procedure sp_add_jobstep...'
  2785. go
  2786. IF (EXISTS (SELECT *
  2787.             FROM msdb.dbo.sysobjects
  2788.             WHERE (name = N'sp_add_jobstep')
  2789.               AND (type = 'P')))
  2790.   DROP PROCEDURE dbo.sp_add_jobstep
  2791. go
  2792. CREATE PROCEDURE dbo.sp_add_jobstep
  2793.   @job_id                UNIQUEIDENTIFIER = NULL,   -- Must provide either this or job_name
  2794.   @job_name              sysname          = NULL,   -- Must provide either this or job_id
  2795.   @step_id               INT              = NULL,   -- The proc assigns a default
  2796.   @step_name             sysname,
  2797.   @subsystem             NVARCHAR(40)     = N'TSQL',
  2798.   @command               NVARCHAR(3201)   = NULL,   -- We declare this as NVARCHAR(3201) not NVARCHAR(3200) so that we can catch 'silent truncation' of commands
  2799.   @additional_parameters NTEXT            = NULL,
  2800.   @cmdexec_success_code  INT              = 0,
  2801.   @on_success_action     TINYINT          = 1,      -- 1 = Quit With Success, 2 = Quit With Failure, 3 = Goto Next Step, 4 = Goto Step
  2802.   @on_success_step_id    INT              = 0,
  2803.   @on_fail_action        TINYINT          = 2,      -- 1 = Quit With Success, 2 = Quit With Failure, 3 = Goto Next Step, 4 = Goto Step
  2804.   @on_fail_step_id       INT              = 0,
  2805.   @server                NVARCHAR(30)      = NULL,
  2806.   @database_name         sysname          = NULL,
  2807.   @database_user_name    sysname          = NULL,
  2808.   @retry_attempts        INT              = 0,      -- No retries
  2809.   @retry_interval        INT              = 0,      -- 0 minute interval
  2810.   @os_run_priority       INT              = 0,      -- -15 = Idle, -1 = Below Normal, 0 = Normal, 1 = Above Normal, 15 = Time Critical)
  2811.   @output_file_name      NVARCHAR(200)    = NULL,
  2812.   @flags                 INT              = 0       -- 0 = Normal, 1 = Encrypted command (read only), 2 = Append output files (if any), 4 = Write TSQL step output to step history
  2813. AS
  2814. BEGIN
  2815.   DECLARE @retval      INT
  2816.  
  2817.   SET NOCOUNT ON
  2818.  
  2819.   -- Only sysadmin's or db_owner's of msdb can add replication job steps directly
  2820.   IF (UPPER(@subsystem collate SQL_Latin1_General_CP1_CS_AS) IN
  2821.                         (N'DISTRIBUTION',
  2822.                          N'SNAPSHOT',
  2823.                          N'LOGREADER',
  2824.                          N'MERGE',
  2825.                          N'QUEUEREADER'))
  2826.   BEGIN
  2827.     IF NOT ((ISNULL(IS_SRVROLEMEMBER(N'sysadmin'), 0) = 1) OR
  2828.             (ISNULL(IS_MEMBER(N'db_owner'), 0) = 1) OR
  2829.             (UPPER(USER_NAME()) = N'DBO'))
  2830.     BEGIN
  2831.       RAISERROR(14260, -1, -1)
  2832.       RETURN(1) -- Failure
  2833.     END
  2834.   END
  2835.  
  2836.   EXECUTE @retval = dbo.sp_add_jobstep_internal @job_id = @job_id,
  2837.                                                 @job_name = @job_name,
  2838.                                                 @step_id = @step_id,
  2839.                                                 @step_name = @step_name,
  2840.                                                 @subsystem = @subsystem,
  2841.                                                 @command = @command,
  2842.                                                 @additional_parameters = @additional_parameters,
  2843.                                                 @cmdexec_success_code = @cmdexec_success_code,
  2844.                                                 @on_success_action = @on_success_action,
  2845.                                                 @on_success_step_id = @on_success_step_id,
  2846.                                                 @on_fail_action = @on_fail_action,
  2847.                                                 @on_fail_step_id = @on_fail_step_id,
  2848.                                                 @server = @server,
  2849.                                                 @database_name = @database_name,
  2850.                                                 @database_user_name = @database_user_name,
  2851.                                                 @retry_attempts = @retry_attempts,
  2852.                                                 @retry_interval = @retry_interval,
  2853.                                                 @os_run_priority = @os_run_priority,
  2854.                                                 @output_file_name = @output_file_name,
  2855.                                                 @flags = @flags
  2856.  
  2857.   RETURN(@retval)
  2858. END
  2859. GO
  2860.  
  2861. grant execute on sp_add_jobstep to public
  2862. go
  2863.  
  2864. /**************************************************************/
  2865. /* SP_UPDATE_JOBSTEP                                          */
  2866. /**************************************************************/
  2867.  
  2868. PRINT ''
  2869. PRINT 'Creating procedure sp_update_jobstep...'
  2870. go
  2871. IF (EXISTS (SELECT *
  2872.             FROM msdb.dbo.sysobjects
  2873.             WHERE (name = N'sp_update_jobstep')
  2874.               AND (type = 'P')))
  2875.   DROP PROCEDURE sp_update_jobstep
  2876. go
  2877. CREATE PROCEDURE sp_update_jobstep
  2878.   @job_id                 UNIQUEIDENTIFIER = NULL, -- Must provide either this or job_name
  2879.   @job_name               sysname          = NULL, -- Not updatable (provided for identification purposes only)
  2880.   @step_id                INT,                     -- Not updatable (provided for identification purposes only)
  2881.   @step_name              sysname          = NULL,
  2882.   @subsystem              NVARCHAR(40)     = NULL,
  2883.   @command                NVARCHAR(3201)   = NULL, -- We declare this as NVARCHAR(3201) not NVARCHAR(3200) so that we can catch 'silent truncation' of commands
  2884.   @additional_parameters  NTEXT            = NULL,
  2885.   @cmdexec_success_code   INT              = NULL,
  2886.   @on_success_action      TINYINT          = NULL,
  2887.   @on_success_step_id     INT              = NULL,
  2888.   @on_fail_action         TINYINT          = NULL,
  2889.   @on_fail_step_id        INT              = NULL,
  2890.   @server                 NVARCHAR(30)     = NULL,
  2891.   @database_name          sysname          = NULL,
  2892.   @database_user_name     sysname          = NULL,
  2893.   @retry_attempts         INT              = NULL,
  2894.   @retry_interval         INT              = NULL,
  2895.   @os_run_priority        INT              = NULL,
  2896.   @output_file_name       NVARCHAR(200)    = NULL,
  2897.   @flags                  INT              = NULL
  2898. AS
  2899. BEGIN
  2900.   DECLARE @retval                 INT
  2901.   DECLARE @os_run_priority_code   INT
  2902.   DECLARE @step_id_as_char        VARCHAR(10)
  2903.   DECLARE @new_step_name          sysname
  2904.  
  2905.   DECLARE @x_step_name            sysname
  2906.   DECLARE @x_subsystem            NVARCHAR(40)
  2907.   DECLARE @x_command              NVARCHAR(3200)
  2908.   DECLARE @x_flags                INT
  2909.   DECLARE @x_cmdexec_success_code INT
  2910.   DECLARE @x_on_success_action    TINYINT
  2911.   DECLARE @x_on_success_step_id   INT
  2912.   DECLARE @x_on_fail_action       TINYINT
  2913.   DECLARE @x_on_fail_step_id      INT
  2914.   DECLARE @x_server               NVARCHAR(30)
  2915.   DECLARE @x_database_name        sysname
  2916.   DECLARE @x_database_user_name   sysname
  2917.   DECLARE @x_retry_attempts       INT
  2918.   DECLARE @x_retry_interval       INT
  2919.   DECLARE @x_os_run_priority      INT
  2920.   DECLARE @x_output_file_name     NVARCHAR(200)
  2921.   DECLARE @x_last_run_outcome     TINYINT      -- Not updatable (but may be in future)
  2922.   DECLARE @x_last_run_duration    INT          -- Not updatable (but may be in future)
  2923.   DECLARE @x_last_run_retries     INT          -- Not updatable (but may be in future)
  2924.   DECLARE @x_last_run_date        INT          -- Not updatable (but may be in future)
  2925.   DECLARE @x_last_run_time        INT          -- Not updatable (but may be in future)
  2926.  
  2927.   SET NOCOUNT ON
  2928.  
  2929.   -- Remove any leading/trailing spaces from parameters
  2930.   SELECT @step_name          = LTRIM(RTRIM(@step_name))
  2931.   SELECT @subsystem          = LTRIM(RTRIM(@subsystem))
  2932.   SELECT @command            = LTRIM(RTRIM(@command))
  2933.   SELECT @server             = LTRIM(RTRIM(@server))
  2934.   SELECT @database_name      = LTRIM(RTRIM(@database_name))
  2935.   SELECT @database_user_name = LTRIM(RTRIM(@database_user_name))
  2936.   SELECT @output_file_name   = LTRIM(RTRIM(@output_file_name))
  2937.  
  2938.   -- Only sysadmin's or db_owner's of msdb can directly change
  2939.   -- an existing job step to use one of the replication
  2940.   -- subsystems
  2941.   IF (UPPER(@subsystem collate SQL_Latin1_General_CP1_CS_AS) IN
  2942.                         (N'DISTRIBUTION',
  2943.                          N'SNAPSHOT',
  2944.                          N'LOGREADER',
  2945.                          N'MERGE',
  2946.                          N'QUEUEREADER'))
  2947.   BEGIN
  2948.     IF NOT ((ISNULL(IS_SRVROLEMEMBER(N'sysadmin'), 0) = 1) OR
  2949.             (ISNULL(IS_MEMBER(N'db_owner'), 0) = 1) OR
  2950.             (UPPER(USER_NAME()) = N'DBO'))
  2951.     BEGIN
  2952.       RAISERROR(14260, -1, -1)
  2953.       RETURN(1) -- Failure
  2954.     END
  2955.   END
  2956.  
  2957.   EXECUTE @retval = sp_verify_job_identifiers '@job_name',
  2958.                                               '@job_id',
  2959.                                                @job_name OUTPUT,
  2960.                                                @job_id   OUTPUT
  2961.   IF (@retval <> 0)
  2962.     RETURN(1) -- Failure
  2963.  
  2964.   -- Check that the step exists
  2965.   IF (NOT EXISTS (SELECT *
  2966.                   FROM msdb.dbo.sysjobsteps
  2967.                   WHERE (job_id = @job_id)
  2968.                     AND (step_id = @step_id)))
  2969.   BEGIN
  2970.     SELECT @step_id_as_char = CONVERT(VARCHAR(10), @step_id)
  2971.     RAISERROR(14262, -1, -1, '@step_id', @step_id_as_char)
  2972.     RETURN(1) -- Failure
  2973.   END
  2974.  
  2975.   -- Check authority (only SQLServerAgent can modify a step of a non-local job)
  2976.   EXECUTE @retval = sp_verify_jobproc_caller @job_id = @job_id, @program_name = N'SQLAgent%'
  2977.   IF (@retval <> 0)
  2978.     RETURN(@retval)
  2979.  
  2980.   -- Set the x_ (existing) variables
  2981.   SELECT @x_step_name            = step_name,
  2982.          @x_subsystem            = subsystem,
  2983.          @x_command              = command,
  2984.          @x_flags                = flags,
  2985.          @x_cmdexec_success_code = cmdexec_success_code,
  2986.          @x_on_success_action    = on_success_action,
  2987.          @x_on_success_step_id   = on_success_step_id,
  2988.          @x_on_fail_action       = on_fail_action,
  2989.          @x_on_fail_step_id      = on_fail_step_id,
  2990.          @x_server               = server,
  2991.          @x_database_name        = database_name,
  2992.          @x_database_user_name   = database_user_name,
  2993.          @x_retry_attempts       = retry_attempts,
  2994.          @x_retry_interval       = retry_interval,
  2995.          @x_os_run_priority      = os_run_priority,
  2996.          @x_output_file_name     = output_file_name,
  2997.          @x_last_run_outcome     = last_run_outcome,
  2998.          @x_last_run_duration    = last_run_duration,
  2999.          @x_last_run_retries     = last_run_retries,
  3000.          @x_last_run_date        = last_run_date,
  3001.          @x_last_run_time        = last_run_time
  3002.   FROM msdb.dbo.sysjobsteps
  3003.   WHERE (job_id = @job_id)
  3004.     AND (step_id = @step_id)
  3005.  
  3006.   IF ((@step_name IS NOT NULL) AND (@step_name <> @x_step_name))
  3007.     SELECT @new_step_name = @step_name
  3008.  
  3009.   -- Fill out the values for all non-supplied parameters from the existing values
  3010.   IF (@step_name            IS NULL) SELECT @step_name            = @x_step_name
  3011.   IF (@subsystem            IS NULL) SELECT @subsystem            = @x_subsystem
  3012.   IF (@command              IS NULL) SELECT @command              = @x_command
  3013.   IF (@flags                IS NULL) SELECT @flags                = @x_flags
  3014.   IF (@cmdexec_success_code IS NULL) SELECT @cmdexec_success_code = @x_cmdexec_success_code
  3015.   IF (@on_success_action    IS NULL) SELECT @on_success_action    = @x_on_success_action
  3016.   IF (@on_success_step_id   IS NULL) SELECT @on_success_step_id   = @x_on_success_step_id
  3017.   IF (@on_fail_action       IS NULL) SELECT @on_fail_action       = @x_on_fail_action
  3018.   IF (@on_fail_step_id      IS NULL) SELECT @on_fail_step_id      = @x_on_fail_step_id
  3019.   IF (@server               IS NULL) SELECT @server               = @x_server
  3020.   IF (@database_name        IS NULL) SELECT @database_name        = @x_database_name
  3021.   IF (@database_user_name   IS NULL) SELECT @database_user_name   = @x_database_user_name
  3022.   IF (@retry_attempts       IS NULL) SELECT @retry_attempts       = @x_retry_attempts
  3023.   IF (@retry_interval       IS NULL) SELECT @retry_interval       = @x_retry_interval
  3024.   IF (@os_run_priority      IS NULL) SELECT @os_run_priority      = @x_os_run_priority
  3025.   IF (@output_file_name     IS NULL) SELECT @output_file_name     = @x_output_file_name
  3026.  
  3027.   -- Turn [nullable] empty string parameters into NULLs
  3028.   IF (@command            = N'') SELECT @command            = NULL
  3029.   IF (@server             = N'') SELECT @server             = NULL
  3030.   IF (@database_name      = N'') SELECT @database_name      = NULL
  3031.   IF (@database_user_name = N'') SELECT @database_user_name = NULL
  3032.   IF (@output_file_name   = N'') SELECT @output_file_name   = NULL
  3033.  
  3034.   -- Check new values
  3035.   EXECUTE @retval = sp_verify_jobstep @job_id,
  3036.                                       @step_id,
  3037.                                       @new_step_name,
  3038.                                       @subsystem,
  3039.                                       @command,
  3040.                                       @server,
  3041.                                       @on_success_action,
  3042.                                       @on_success_step_id,
  3043.                                       @on_fail_action,
  3044.                                       @on_fail_step_id,
  3045.                                       @os_run_priority,
  3046.                                       @database_name      OUTPUT,
  3047.                                       @database_user_name OUTPUT,
  3048.                                       @flags,
  3049.                                       @output_file_name
  3050.   IF (@retval <> 0)
  3051.     RETURN(1) -- Failure
  3052.  
  3053.   BEGIN TRANSACTION
  3054.  
  3055.     -- Update the job's version/last-modified information
  3056.     UPDATE msdb.dbo.sysjobs
  3057.     SET version_number = version_number + 1,
  3058.         date_modified = GETDATE()
  3059.     WHERE (job_id = @job_id)
  3060.  
  3061.     -- Update the step
  3062.     UPDATE msdb.dbo.sysjobsteps
  3063.     SET step_name             = @step_name,
  3064.         subsystem             = @subsystem,
  3065.         command               = @command,
  3066.         flags                 = @flags,
  3067.         cmdexec_success_code  = @cmdexec_success_code,
  3068.         on_success_action     = @on_success_action,
  3069.         on_success_step_id    = @on_success_step_id,
  3070.         on_fail_action        = @on_fail_action,
  3071.         on_fail_step_id       = @on_fail_step_id,
  3072.         server                = @server,
  3073.         database_name         = @database_name,
  3074.         database_user_name    = @database_user_name,
  3075.         retry_attempts        = @retry_attempts,
  3076.         retry_interval        = @retry_interval,
  3077.         os_run_priority       = @os_run_priority,
  3078.         output_file_name      = @output_file_name,
  3079.         last_run_outcome      = @x_last_run_outcome,
  3080.         last_run_duration     = @x_last_run_duration,
  3081.         last_run_retries      = @x_last_run_retries,
  3082.         last_run_date         = @x_last_run_date,
  3083.         last_run_time         = @x_last_run_time
  3084.     WHERE (job_id = @job_id)
  3085.       AND (step_id = @step_id)
  3086.  
  3087.     -- Since we can't declare TEXT parameters (and therefore use the @x_ technique) we handle
  3088.     -- @additional_parameters as a special case...
  3089.     IF (@additional_parameters IS NOT NULL)
  3090.     BEGIN
  3091.       UPDATE msdb.dbo.sysjobsteps
  3092.       SET additional_parameters = @additional_parameters
  3093.       WHERE (job_id = @job_id)
  3094.         AND (step_id = @step_id)
  3095.     END
  3096.  
  3097.   COMMIT TRANSACTION
  3098.  
  3099.   -- For a multi-server job, remind the user that they need to call sp_post_msx_operation
  3100.   IF (EXISTS (SELECT *
  3101.               FROM msdb.dbo.sysjobservers
  3102.               WHERE (job_id = @job_id)
  3103.                 AND (server_id <> 0)))
  3104.     RAISERROR(14547, 0, 1, N'INSERT', N'sp_post_msx_operation')
  3105.  
  3106.   RETURN(0) -- Success
  3107. END
  3108. go
  3109.  
  3110. grant execute on sp_update_jobstep to public
  3111. go
  3112.  
  3113. /**************************************************************/
  3114. /* xp_sqlagent_msx_account                                                                                   */
  3115. /**************************************************************/
  3116. use master
  3117. go
  3118.  
  3119. if exists (select * from master.dbo.sysobjects where name = N'xp_sqlagent_msx_account' and type = N'X')
  3120.     exec sp_dropextendedproc N'xp_sqlagent_msx_account'
  3121. go
  3122.  
  3123. print ''
  3124. print N'Creating extended stored procedure xp_sqlagent_msx_account'
  3125. go
  3126. exec sp_addextendedproc N'xp_sqlagent_msx_account',N'xpstar.dll'
  3127. go
  3128.  
  3129. use msdb
  3130. go
  3131.  
  3132. DENY ALL ON sp_add_jobserver     TO TargetServersRole
  3133. DENY ALL ON sp_delete_jobserver  TO TargetServersRole
  3134.  
  3135. DENY ALL ON sp_add_jobstep    TO TargetServersRole
  3136. DENY ALL ON sp_update_jobstep TO TargetServersRole
  3137. DENY ALL ON sp_delete_jobstep TO TargetServersRole
  3138.  
  3139. DENY ALL ON sp_add_jobschedule    TO TargetServersRole
  3140. DENY ALL ON sp_update_jobschedule TO TargetServersRole
  3141. DENY ALL ON sp_delete_jobschedule TO TargetServersRole
  3142.  
  3143. DENY ALL ON sp_add_job    TO TargetServersRole
  3144. DENY ALL ON sp_update_job TO TargetServersRole
  3145. DENY ALL ON sp_delete_job TO TargetServersRole
  3146. DENY ALL ON sp_start_job  TO TargetServersRole
  3147. DENY ALL ON sp_stop_job   TO TargetServersRole
  3148.  
  3149. DENY ALL ON sp_post_msx_operation       TO TargetServersRole
  3150.  
  3151. DENY ALL ON sp_addtask        TO TargetServersRole
  3152. DENY ALL ON sp_updatetask     TO TargetServersRole
  3153. DENY ALL ON sp_droptask       TO TargetServersRole
  3154. DENY ALL ON sp_reassigntask   TO TargetServersRole
  3155. DENY ALL ON sp_purgehistory   TO TargetServersRole
  3156.  
  3157. go
  3158. --------------------------------------------------------------------------------
  3159. -- END AGENT SECTION
  3160. --------------------------------------------------------------------------------
  3161.  
  3162.  
  3163. --------------------------------------------------------------------------------
  3164. -- Remove public right from xp_SetSQLSecurity
  3165. -- This updates script from xpstar.sql
  3166. --------------------------------------------------------------------------------
  3167. use master
  3168. go
  3169.  
  3170. if exists (select * from sysobjects
  3171.         where name = N'xp_SetSQLSecurity')
  3172.     execute dbo.sp_dropextendedproc N'xp_SetSQLSecurity'
  3173. go
  3174.  
  3175. print N'Creating extended stored procedure xp_SetSQLSecurity'
  3176. exec sp_addextendedproc N'xp_SetSQLSecurity',N'xpstar.dll'
  3177. go
  3178.  
  3179. --------------------------------------------------------------------------------
  3180. -- XPWEB stored procedures and table modified for SP3
  3181. --
  3182. -- changed permissions on msdb..MSwebtasks table (sysadmin can INSERT, UPDATE, 
  3183. --    DELETE, public can SELECT only)
  3184. -- changed permissions on following stored procedures (ony sysadmin can EXECUTE):
  3185. --  sp_makewebtask
  3186. --  sp_dropwebtask
  3187. --  sp_cleanupwebtask
  3188. --------------------------------------------------------------------------------
  3189.  
  3190. -- Add mswebtasks table if not there
  3191. USE msdb
  3192. IF EXISTS (SELECT * FROM sysobjects WHERE name = N'mswebtasks')
  3193. BEGIN
  3194.    REVOKE INSERT ON mswebtasks FROM PUBLIC
  3195.    REVOKE DELETE ON mswebtasks FROM PUBLIC
  3196.    REVOKE UPDATE ON mswebtasks FROM PUBLIC
  3197. END
  3198. go
  3199.  
  3200. REVOKE EXECUTE ON sp_insmswebtask FROM PUBLIC
  3201. go
  3202. REVOKE EXECUTE ON sp_updmswebtask FROM PUBLIC
  3203. go
  3204.  
  3205.  
  3206. -- Revoke privileges on stored procedures
  3207. USE master
  3208. go
  3209. REVOKE EXECUTE ON sp_makewebtask FROM PUBLIC
  3210. go
  3211. REVOKE EXECUTE ON sp_dropwebtask FROM PUBLIC
  3212. go
  3213. REVOKE EXECUTE ON sp_cleanupwebtask FROM PUBLIC
  3214. go
  3215.  
  3216. --------------------------------------------------------------------------------
  3217. -- END XPWEB SECTION
  3218. --------------------------------------------------------------------------------
  3219.  
  3220. --------------------------------------------------------------------------------
  3221. -- Change permissions on Repository stored procedures, table, and views
  3222. --------------------------------------------------------------------------------
  3223.  
  3224. use msdb
  3225. go
  3226.  
  3227. /***
  3228.    Make sure repository tables exist
  3229. ***/
  3230. if exists (select * from sysobjects where type = 'U' AND name = 'RTblIfaceDefs')
  3231. begin
  3232.  
  3233.     /***
  3234.        Add new security role
  3235.     ***/
  3236.     if not exists (select * from sysusers where name = 'RepositoryUser')
  3237.         exec sp_addrole 'RepositoryUser'
  3238.  
  3239.     declare @ExecStmt as nvarchar(255)
  3240.  
  3241.     /***
  3242.        Remove public role from repository tables
  3243.     ***/
  3244.     DECLARE TmpCursor CURSOR FOR
  3245.     select distinct 'revoke all on ' + SQLTableName + ' to public'  from RTblIfaceDefs inner join sysobjects on SQLTableName = name where SQLTableName <> ''
  3246.     union
  3247.     select 'revoke all on ' + name + ' to public'  from sysobjects where type = 'U' AND name like 'RTbl%'
  3248.      
  3249.     OPEN TmpCursor
  3250.     FETCH NEXT FROM TmpCursor into @ExecStmt
  3251.     WHILE @@FETCH_STATUS = 0
  3252.     BEGIN
  3253.         exec sp_executesql @ExecStmt
  3254.         FETCH NEXT FROM TmpCursor into @ExecStmt
  3255.     END
  3256.     CLOSE TmpCursor
  3257.     DEALLOCATE TmpCursor
  3258.      
  3259.     /***
  3260.        Grant permissions on new role on repository tables
  3261.     ***/
  3262.     DECLARE TmpCursor CURSOR FOR
  3263.     select distinct 'grant all on ' + SQLTableName + ' to RepositoryUser'  from RTblIfaceDefs inner join sysobjects on SQLTableName = name where SQLTableName <> ''
  3264.     union
  3265.     select 'grant all on ' + name + ' to RepositoryUser'  from sysobjects where type = 'U' AND name like 'RTbl%'
  3266.      
  3267.     OPEN TmpCursor
  3268.     FETCH NEXT FROM TmpCursor into @ExecStmt
  3269.     WHILE @@FETCH_STATUS = 0
  3270.     BEGIN
  3271.         exec sp_executesql @ExecStmt
  3272.         FETCH NEXT FROM TmpCursor into @ExecStmt
  3273.     END
  3274.     CLOSE TmpCursor
  3275.     DEALLOCATE TmpCursor
  3276.      
  3277.     /***
  3278.        Remove public role from repository stored procedures
  3279.     ***/
  3280.     DECLARE TmpCursor CURSOR FOR
  3281.     select 'revoke all on ' + name + ' to public'  from sysobjects where type = 'P' AND name like 'r_i%'
  3282.      
  3283.     OPEN TmpCursor
  3284.     FETCH NEXT FROM TmpCursor into @ExecStmt
  3285.     WHILE @@FETCH_STATUS = 0
  3286.     BEGIN
  3287.         exec sp_executesql @ExecStmt
  3288.         FETCH NEXT FROM TmpCursor into @ExecStmt
  3289.     END
  3290.     CLOSE TmpCursor
  3291.     DEALLOCATE TmpCursor
  3292.      
  3293.     /***
  3294.        Grant permissions on new role on repository stored procedures
  3295.     ***/
  3296.     DECLARE TmpCursor CURSOR FOR
  3297.     select 'grant all on ' + name + ' to RepositoryUser'  from sysobjects where type = 'P' AND name like 'r_i%'
  3298.      
  3299.     OPEN TmpCursor
  3300.     FETCH NEXT FROM TmpCursor into @ExecStmt
  3301.     WHILE @@FETCH_STATUS = 0
  3302.     BEGIN
  3303.         exec sp_executesql @ExecStmt
  3304.         FETCH NEXT FROM TmpCursor into @ExecStmt
  3305.     END
  3306.     CLOSE TmpCursor
  3307.     DEALLOCATE TmpCursor
  3308.      
  3309.     IF EXISTS (select DatabaseVersion from RTblDatabaseVersion WHERE DatabaseVersion LIKE '3.%')
  3310.     BEGIN
  3311.         /***
  3312.            Remove public role from repository views (only on V3)
  3313.         ***/
  3314.         EXEC sp_executesql N'DECLARE TmpCursor CURSOR FOR SELECT DISTINCT ''revoke all on '' + ViewName + '' to public''  FROM RTblIfaceDefs WHERE ViewName <> '''''
  3315.      
  3316.         OPEN TmpCursor
  3317.         FETCH NEXT FROM TmpCursor into @ExecStmt
  3318.         WHILE @@FETCH_STATUS = 0
  3319.         BEGIN
  3320.             exec sp_executesql @ExecStmt
  3321.             FETCH NEXT FROM TmpCursor into @ExecStmt
  3322.         END
  3323.         CLOSE TmpCursor
  3324.         DEALLOCATE TmpCursor
  3325.     
  3326.         /***
  3327.            Grant permissions on new role on repository views (only on V3)
  3328.         ***/
  3329.         EXEC sp_executesql N'DECLARE TmpCursor CURSOR FOR SELECT DISTINCT ''grant all on '' + ViewName + '' to RepositoryUser''  FROM RTblIfaceDefs WHERE ViewName <> '''''
  3330.      
  3331.         OPEN TmpCursor
  3332.         FETCH NEXT FROM TmpCursor into @ExecStmt
  3333.         WHILE @@FETCH_STATUS = 0
  3334.         BEGIN
  3335.             exec sp_executesql @ExecStmt
  3336.             FETCH NEXT FROM TmpCursor into @ExecStmt
  3337.         END
  3338.         CLOSE TmpCursor
  3339.         DEALLOCATE TmpCursor
  3340.     END
  3341.  
  3342. END
  3343.  
  3344. USE master
  3345. go
  3346.  
  3347. --------------------------------------------------------------------------------
  3348. -- End Repository Changes
  3349. --------------------------------------------------------------------------------
  3350.  
  3351.  
  3352. --------------------------------------------------------------------------------
  3353. -- END OF CHANGE SECTION:
  3354. -- Turn off marking of system objects.
  3355. -- DO NOT ADD ANYTHING AFTER THIS POINT
  3356. --------------------------------------------------------------------------------
  3357. print N''
  3358. go
  3359.  
  3360. exec sp_MS_upd_sysobj_category 2
  3361. go
  3362.  
  3363. exec sp_configure 'allow updates',0
  3364. go
  3365.  
  3366. reconfigure with override
  3367. go
  3368.  
  3369. PRINT N''
  3370. PRINT N'Done updating database objects'
  3371. PRINT N'Finished at ' + convert(nvarchar(25), getdate())
  3372. PRINT N''
  3373. go
  3374.  
  3375.  
  3376. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = N'sp_MSSetServerProperties')
  3377.     drop procedure sp_MSSetServerProperties
  3378. go
  3379.  
  3380.  
  3381. print N''
  3382. print N'Creating sp_MSSetServerProperties'
  3383. print N''
  3384. go
  3385.  
  3386. create proc sp_MSSetServerProperties
  3387.    @auto_start    INT   = NULL   -- 1 or 0, while 1 = auto start, 0 = manual start
  3388. as
  3389.    set nocount on
  3390.  
  3391.    -- only sysadmins are allowed to execute this stored procedure
  3392.    if( is_srvrolemember(N'sysadmin') = 0 )
  3393.        begin
  3394.        RAISERROR (15003, -1, -1, N'sysadmin')
  3395.        return 1
  3396.        end
  3397.  
  3398.    -- Make sure values (if supplied) are good
  3399.    IF (@auto_start IS NOT NULL)
  3400.    BEGIN
  3401.       -- NOTE: When setting the the services start value, 2 == auto-start, 3 == Don't auto-start
  3402.       SELECT @auto_start = CASE @auto_start
  3403.                            WHEN 0 THEN 3
  3404.                            WHEN 1 THEN 2
  3405.                            ELSE 3 -- Assume non auto-start if passed a junk value
  3406.                            END
  3407.    END
  3408.  
  3409.    -- Write out the values
  3410.    IF (@auto_start IS NOT NULL)
  3411.    BEGIN
  3412.       IF ((PLATFORM() & 0x1) = 0x1) -- NT
  3413.          EXECUTE master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE',
  3414.                                                  N'SYSTEM\CurrentControlSet\Services\MSSQLServer',
  3415.                                                  N'Start',
  3416.                                                  N'REG_DWORD',
  3417.                                                  @auto_start
  3418.       ELSE
  3419.          RAISERROR(14546, 16, 1, '@auto_start')
  3420.    END
  3421.  
  3422. go
  3423. /* End sp_MSSetServerProperties */
  3424.  
  3425.  
  3426. exec sp_MS_marksystemobject sp_MSSetServerProperties
  3427. go
  3428.  
  3429.  
  3430. if exists (select * from master.dbo.sysobjects where (OBJECTPROPERTY(id, N'IsProcedure') = 1 or OBJECTPROPERTY(id, N'IsExtendedProc') = 1) and name = 'sp_MSsetalertinfo')
  3431.     drop procedure sp_MSsetalertinfo
  3432. go
  3433.  
  3434.  
  3435. /*-----------------------------------------------------*/
  3436. /*-----------------------------------------------------*/
  3437. print N''
  3438. print N'Creating sp_MSsetalertinfo'
  3439. print N''
  3440. go
  3441. create procedure sp_MSsetalertinfo
  3442.     @failsafeoperator nvarchar(255) = null,
  3443.     @notificationmethod int = null,
  3444.     @forwardingserver nvarchar(255) = null,
  3445.     @forwardingseverity int = null,
  3446.     @pagertotemplate nvarchar(255) = null,
  3447.     @pagercctemplate nvarchar(255) = null,
  3448.     @pagersubjecttemplate nvarchar(255) = null,
  3449.     @pagersendsubjectonly int = null,
  3450.     @failsafeemailaddress nvarchar(255) = null,
  3451.     @failsafepageraddress nvarchar(255) = null,
  3452.     @failsafenetsendaddress nvarchar(255) = null,
  3453.     @forwardalways int = null -- 0 = forward only unhandled events, 1 = always forward events (both subject to @forwardingseverity)
  3454. as
  3455.  
  3456.    -- only sysadmins are allowed to execute this stored procedure
  3457.    if( is_srvrolemember(N'sysadmin') = 0 )
  3458.        begin
  3459.        RAISERROR (15003, -1, -1, N'sysadmin')
  3460.        return 1
  3461.        end
  3462.  
  3463.     /* Set all alert info at one go, for performance reasons.  Translate values if needed. */
  3464.     if (@pagersendsubjectonly is not null and @pagersendsubjectonly <> 0)
  3465.         select @pagersendsubjectonly = 1
  3466.  
  3467.     if (@failsafeoperator is not null)
  3468.         exec master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertFailSafeOperator', N'REG_SZ', @failsafeoperator
  3469.     if (@notificationmethod is not null)
  3470.         exec master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertNotificationMethod', N'REG_DWORD', @notificationmethod
  3471.     if (@forwardingserver is not null)
  3472.         exec master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertForwardingServer', N'REG_SZ', @forwardingserver
  3473.     if (@forwardingseverity is not null)
  3474.         exec master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertForwardingSeverity', N'REG_DWORD', @forwardingseverity
  3475.     if (@pagertotemplate is not null)
  3476.         exec master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertPagerToTemplate', N'REG_SZ', @pagertotemplate
  3477.     if (@pagercctemplate is not null)
  3478.         exec master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertPagerCCTemplate', N'REG_SZ', @pagercctemplate
  3479.     if (@pagersubjecttemplate is not null)
  3480.         exec master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertPagerSubjectTemplate', N'REG_SZ', @pagersubjecttemplate
  3481.     if (@pagersendsubjectonly is not null)
  3482.         exec master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertPagerSendSubjectOnly', N'REG_DWORD', @pagersendsubjectonly
  3483.     if (@failsafeemailaddress is not null)
  3484.         exec master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertFailSafeEmailAddress', N'REG_SZ', @failsafeemailaddress
  3485.     if (@failsafepageraddress is not null)
  3486.         exec master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertFailSafePagerAddress', N'REG_SZ', @failsafepageraddress
  3487.     if (@failsafenetsendaddress is not null)
  3488.         exec master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertFailSafeNetSendAddress', N'REG_SZ', @failsafenetsendaddress
  3489.     if (@forwardalways is not null)
  3490.         exec master.dbo.xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent', N'AlertForwardAlways', N'REG_DWORD', @forwardalways
  3491. go
  3492. /* End sp_MSgetalertinfo */
  3493.  
  3494. exec sp_MS_marksystemobject sp_MSsetalertinfo
  3495. go
  3496.  
  3497.  
  3498.